94 votes

Sérialiser un int nullable

J'ai une classe avec un nullable int? type de données défini pour sérialiser comme un élément xml. Est-il possible de configurer de sorte que le xml serialializer ne sera pas sérialiser l'élément si la valeur est null?

J'ai essayé d'ajouter le bouton [System.Xml.La sérialisation.XmlElement(IsNullable=false)] attribut, mais je reçois un moteur d'exécution de sérialisation exception disant qu'il y avait une erreur, reflétant le type, parce que "IsNullable ne peut pas être réglé à 'false' pour un type Nullable. Pensez à utiliser le Système de la.Int32 de type ou de retrait de la IsNullable bien de la XmlElement attribut."

[Serializable]
[System.Xml.Serialization.XmlRoot("Score", Namespace = "http://mycomp.com/test/score/v1")]
public class Score
{
    private int? iID_m;
    ...

    /// <summary>
    /// 
    /// </summary>        
    public int? ID 
    { 
        get 
        { 
            return iID_m; 
        } 
        set 
        { 
            iID_m = value; 
        } 
    }
     ...
}

La classe ci-dessus sera serailize:

<Score xmlns="http://mycomp.com/test/score/v1">
    <ID xsi:nil="true" />
</Score>

Mais pour que les Id sont nulles je ne veux pas l'ID de l'élément à tous, principalement parce que lorsque j'utilise OPENXML dans MSSQL, elle retourne la valeur 0 au lieu de null pour un élément qui ressemble à

155voto

Marc Gravell Points 482669

XmlSerializer prend en charge le `` pattern, afin que vous pouvez ajouter une méthode :

Il y a aussi le `` modèle - ne sais pas si XmlSerializer prend en charge qu’un.

28voto

David Schmitt Points 29384

J’utilise cet micro-modèle à implémentent la sérialisation Nullable :

Ceci fournit la bonne interface à l’utilisateur sans compromis et fait toujours la bonne chose lors de la sérialisation.

12voto

Jeremy Points 14078

J’ai trouvé une solution de contournement utilisant deux propriétés. Un int ? propriété avec un attribut XmlIgnore et une propriété d’objet qui est sérialisée.

6voto

Scott Bilas Points 4958

Wow merci à cette question/réponse m'a vraiment aidé. J'cœur Stackoverflow.

J'ai fait ce que vous faites au-dessus un peu plus générique. Tout ce que nous sommes vraiment à la recherche de est à ont Nullable légèrement différentes de sérialisation de comportement. J'ai utilisé un Réflecteur pour construire mon propre Nullable, et a ajouté quelques petites choses ici et là pour faire de la sérialisation XML travail de la façon dont nous voulons. Semble fonctionner assez bien:

public class Nullable<T>
{
    public Nullable(T value)
    {
        _value = value;
        _hasValue = true;
    }

    public Nullable()
    {
        _hasValue = false;
    }

    [XmlText]
    public T Value
    {
        get
        {
            if (!HasValue)
                throw new InvalidOperationException();
            return _value;
        }
        set
        {
            _value = value;
            _hasValue = true;
        }
    }

    [XmlIgnore]
    public bool HasValue
        { get { return _hasValue; } }

    public T GetValueOrDefault()
        { return _value; }
    public T GetValueOrDefault(T i_defaultValue)
        { return HasValue ? _value : i_defaultValue; }

    public static explicit operator T(Nullable<T> i_value)
        { return i_value.Value; }
    public static implicit operator Nullable<T>(T i_value)
        { return new Nullable<T>(i_value); }

    public override bool Equals(object i_other)
    {
        if (!HasValue)
            return (i_other == null);
        if (i_other == null)
            return false;
        return _value.Equals(i_other);
    }

    public override int GetHashCode()
    {
        if (!HasValue)
            return 0;
        return _value.GetHashCode();
    }

    public override string ToString()
    {
        if (!HasValue)
            return "";
        return _value.ToString();
    }

    bool _hasValue;
    T    _value;
}

Vous perdez la possibilité d'avoir vos membres, comme des int? et ainsi de suite (utiliser Nullable<int> au lieu de cela) mais d'autres que tout le comportement reste le même.

1voto

Malheureusement, les comportements que vous décrivez sont documentés avec précision comme tel dans les docs pour XmlElementAttribute.IsNullable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X