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);
    }
    ...
}