IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Custom Serialization : Désérialisation d'objet nullable


Sujet :

C#

  1. #1
    Membre régulier
    Homme Profil pro
    Architecte technique
    Inscrit en
    Avril 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Avril 2003
    Messages : 79
    Points : 107
    Points
    107
    Par défaut Custom Serialization : Désérialisation d'objet nullable
    Bonjour,

    Je suis confronté à un petit problème :

    J'utilise la sérialisation personnalisée pour sauver/charger l'état d'un objet sur le disque. Cet objet est une instance de classe composite qui contient donc des instances d'autres classes.

    Lorsque je désire désérialiser cette classe, j'ai une SerializationException lorsque la classe contient un membre à null.

    Voici le code de la classe en question :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    public class BeneficiaireInfos : ISerializable
        {
            ...
            public BeneficiaireInfos(SerializationInfo si, StreamingContext context)
            {
     
                ADroitNationalGereParAilleurs = si.GetBoolean("BeneficiaireInfos.ADroitNationalGereParAilleurs");
                ...
                DotationAnnuelleBeneficiaireFamille = new DotationAnnuelleBeneficiaireFamille(si, context);
                ...
            }
     
            /// <summary>
            /// Obtient ou définit une valeur indiquant si le droit national du beneficiaire est géré par ailleurs.
            /// </summary>
            public bool ADroitNationalGereParAilleurs
            {
                get;
                set;
            }
     
            /// <summary>
            /// Obtient ou définit une instance de DotationAnnuelleBeneficiaireFamille contenant les informations du bénéficiaire à stocker en BDD à la fin du calcul de la dotation.
            /// </summary>
            public DotationAnnuelleBeneficiaireFamille DotationAnnuelleBeneficiaireFamille
            {
                get;
                set;
            }
     
             public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue("BeneficiaireInfos.ADroitNationalGereParAilleurs", ADroitNationalGereParAilleurs);
                ...
     
                if (DotationAnnuelleBeneficiaireFamille != null)
                {
                    DotationAnnuelleBeneficiaireFamille.GetObjectData(info, context);
                }
     
                ...
            }
    }
    Et celui de la classe référencée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    public class DotationAnnuelleBeneficiaireFamille : ISerializable
        {
            /// <summary>
            /// Initialise une nouvelle instance de DotationAnnuelleBeneficiaireFamille.
            /// </summary>
            /// <param name="si"></param>
            /// <param name="context"></param>
            public DotationAnnuelleBeneficiaireFamille(SerializationInfo si, StreamingContext context)
            {
                IdDotationAnnuelleBeneficiaireFamille = si.GetInt64("DotationAnnuelleBeneficiaireFamille.IdDotationAnnuelleBeneficiaireFamille");
                ...
            }
     
            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue("DotationAnnuelleBeneficiaireFamille.IdDotationAnnuelleBeneficiaireFamille", IdDotationAnnuelleBeneficiaireFamille);
                ...
            }
    Ce code fonctionne correctement pour des instances de BeneficiaireInfos dont le membre DotationAnnuelleBeneficiaireFamille est non null.

    Par contre pour une instance de BeneficiaireInfos dont le membre DotationAnnuelleBeneficiaireFamille est null l'exception suivante est levée lors de la désérialisation :
    SerializationException
    "Membre 'DotationAnnuelleBeneficiaireFamille.IdDotationAnnuelleBeneficiaireFamille' introuvable."


    Ce qui parait logique vu que l'instance de DotationAnnuelleBeneficiaireFamille n'a pas été sérialisé lors de la sérialisation à cause du test verifiant si le membre est null.

    Ma question n'est donc pas pourquoi j'ai une exception mais comment gère t-on correctement ce cas ?

    J'ai pensé à sérialiser un booleen pour chaque instance de classe indiquant si l'instance est null ou pas et donc de n'appellez le constructeur de la classe que si le booleen est à true. Mais je ne trouve pas ça très élégant...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    public BeneficiaireInfos(SerializationInfo si, StreamingContext context)
    {
        ADroitNationalGereParAilleurs = si.GetBoolean("BeneficiaireInfos.ADroitNationalGereParAilleurs");
        ...
        bool EstNonNullDotationAnnuelleBeneficiaireFamille = si.GetBoolean("BeneficiaireInfos.EstNonNullDotationAnnuelleBeneficiaireFamille ");
     
        if(EstNonNullDotationAnnuelleBeneficiaireFamille)
        {
            DotationAnnuelleBeneficiaireFamille = new DotationAnnuelleBeneficiaireFamille(si, context);
        }
        ...
    }
    ...
     
    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("BeneficiaireInfos.ADroitNationalGereParAilleurs", ADroitNationalGereParAilleurs);
        ...
        if (DotationAnnuelleBeneficiaireFamille != null)
        {
            info.AddValue("BeneficiaireInfos.EstNonNullDotationAnnuelleBeneficiaireFamille", true);
            DotationAnnuelleBeneficiaireFamille.GetObjectData(info, context);
        }
        else
        {
            info.AddValue("BeneficiaireInfos.EstNonNullDotationAnnuelleBeneficiaireFamille", false);
        }
        ...
    }

  2. #2
    Membre régulier
    Homme Profil pro
    Architecte technique
    Inscrit en
    Avril 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Avril 2003
    Messages : 79
    Points : 107
    Points
    107
    Par défaut Résolution
    Je me répond à moi même au cas où ca interesserait qqn :

    Au moment de la sérialisation, remplacer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (DotationAnnuelleBeneficiaireFamille != null)
                {
                    DotationAnnuelleBeneficiaireFamille.GetObjectData(info, context);
                }
    par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    info.AddValue("BeneficiaireInfos.DotationAnnuelleBeneficiaireFamille", DotationAnnuelleBeneficiaireFamille, typeof(DotationAnnuelleBeneficiaireFamille));
    et au moment de la désérialisation, remplacez

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DotationAnnuelleBeneficiaireFamille = new DotationAnnuelleBeneficiaireFamille(si, context);
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DotationAnnuelleBeneficiaireFamille = (DotationAnnuelleBeneficiaireFamille)si.GetValue("BeneficiaireInfos.DotationAnnuelleBeneficiaireFamille", typeof(DotationAnnuelleBeneficiaireFamille));

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. serialize sur un objet
    Par Tchupacabra dans le forum jQuery
    Réponses: 9
    Dernier message: 29/03/2010, 11h14
  2. [XStream] Désérialiser un objet avec une valeur par défaut
    Par djodjo dans le forum Format d'échange (XML, JSON...)
    Réponses: 0
    Dernier message: 21/04/2009, 13h47
  3. Serialization d'un objet
    Par rad_hass dans le forum C#
    Réponses: 3
    Dernier message: 16/12/2008, 19h03
  4. [PDO] Désérialiser un objet provenant d'une table MySQL
    Par kiki650 dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 23/10/2007, 16h20
  5. [RMI][Serialization] Recupérer un objet
    Par mavina dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 04/12/2006, 15h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo