Je reçois un xml à partir de la 3ème partie et j'ai besoin de désérialiser en C# de l'objet. Ce document xml peut contenir des attributs avec une valeur de type entier ou valeur vide: attr="11" ou attr="". Je veux désérialiser cette valeur d'attribut dans la propriété avec le type de nullable entier. Mais XmlSerializer ne prend pas en charge la désérialisation dans les types nullables. Suivants du code de test échoue lors de la création de XmlSerializer avec InvalidOperationException {"Il y a une erreur reflétant type 'TestConsoleApplication.SerializeMe'."}.
[XmlRoot("root")]
public class SerializeMe
{
[XmlElement("element")]
public Element Element { get; set; }
}
public class Element
{
[XmlAttribute("attr")]
public int? Value { get; set; }
}
class Program {
static void Main(string[] args) {
string xml = "<root><element attr=''>valE</element></root>";
var deserializer = new XmlSerializer(typeof(SerializeMe));
Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
var result = (SerializeMe)deserializer.Deserialize(xmlStream);
}
}
Quand je change de type de la "Valeur" des biens de type int, la désérialisation échoue avec InvalidOperationException:
Il y a une erreur dans le document XML (1, 16).
Quelqu'un peut-il conseiller sur la façon de désérialiser attribut avec une valeur vide dans type nullable (null) dans le même temps, la désérialisation de non-vide, la valeur de l'attribut dans l'entier? Est-il une astuce pour cela je n'aurai pas à faire de la désérialisation de chaque champ manuellement (en fait il y en a beaucoup)?
Mise à jour après le commentaire de ahsteele:
-
Autant que je sache, cet attribut ne fonctionne qu'avec XmlElementAttribute - cet attribut indique que l'élément n'a pas de contenu, que ce soit des éléments d'enfant ou le corps du texte. Mais j'ai besoin de trouver la solution pour XmlAttributeAttribute. De toute façon je ne peux pas changer xml, car je n'ai aucun contrôle sur elle.
-
Cette propriété ne fonctionne que lorsque la valeur de l'attribut est non-vide ou quand l'attribut est manquant. Lorsque l'attribut a une valeur vide (attr=") le constructeur de XmlSerializer échoue (comme prévu).
public class Element { [XmlAttribute("attr")] public int Value { get; set; } [XmlIgnore] public bool ValueSpecified; }
-
Personnalisé Nullable classe comme dans cet article de blog par Alex Scordellis
J'ai essayé d'adopter la classe à partir de ce blog à mon problème:
[XmlAttribute("attr")] public NullableInt Value { get; set; }
Mais XmlSerializer constructeur échoue avec InvalidOperationException:
Impossible de sérialiser membre de la "Valeur" de type TestConsoleApplication.NullableInt.
XmlAttribute/XmlText ne peut pas être utilisé pour coder les types de mise en œuvre de IXmlSerializable }
-
Laide de substitution de la solution (honte sur moi que j'ai écrit ce code ici :) ):
public class Element { [XmlAttribute("attr")] public string SetValue { get; set; } public int? GetValue() { if ( string.IsNullOrEmpty(SetValue) || SetValue.Trim().Length <= 0 ) return null; int result; if (int.TryParse(SetValue, out result)) return result; return null; } }
Mais je ne veux pas venir avec la solution de ce genre car il rompt l'interface de ma classe pour ses consommateurs. J'aurais mieux manuellement mettre en œuvre IXmlSerializable interface.
Actuellement, il semble que j'ai à mettre en œuvre IXmlSerializable pour l'ensemble de l'Élément de la classe (il est grand) et il n'existe pas de solution simple...