Ich erhalte eine XML-Datei von einem Drittanbieter und muss sie in ein C # -Objekt deserialisieren. Diese XML-Datei kann Attribute mit einem Wert vom Typ Integer oder einem leeren Wert enthalten: attr = ”11” oder attr = ””. Ich möchte diesen Attributwert in die Eigenschaft mit dem Typ einer nullbaren Ganzzahl deserialisieren. XmlSerializer unterstützt jedoch keine Deserialisierung in nullfähige Typen. Der folgende Testcode schlägt beim Erstellen von XmlSerializer mit InvalidOperationException fehl {"Es ist ein Fehler aufgetreten, der den Typ 'TestConsoleApplication.SerializeMe' widerspiegelt."}.
[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);
}
}
Wenn ich den Typ der 'Value'-Eigenschaft in int ändere, schlägt die Deserialisierung mit InvalidOperationException fehl:
Im XML-Dokument (1, 16) ist ein Fehler aufgetreten.
Kann jemand raten, wie man ein Attribut mit einem leeren Wert in einen nullbaren Typ (als Null) deserialisiert und gleichzeitig einen nicht leeren Attributwert in eine Ganzzahl deserialisiert? Gibt es dafür einen Trick, damit ich nicht jedes Feld manuell deserialisieren muss (tatsächlich gibt es viele davon)?
Update nach Kommentar von ahsteele:
-
Soweit ich weiß, funktioniert dieses Attribut nur mit XmlElementAttribute - dieses Attribut gibt an, dass das Element keinen Inhalt hat, egal ob untergeordnete Elemente oder Textkörper. Aber ich muss die Lösung für XmlAttributeAttribute finden. Auf jeden Fall kann ich XML nicht ändern, da ich keine Kontrolle darüber habe.
-
Diese Eigenschaft funktioniert nur, wenn der Attributwert nicht leer ist oder wenn das Attribut fehlt. Wenn attr einen leeren Wert hat (attr = ''), schlägt der XmlSerializer-Konstruktor fehl (wie erwartet).
public class Element { [XmlAttribute("attr")] public int Value { get; set; } [XmlIgnore] public bool ValueSpecified; }
Benutzerdefinierte Nullable-Klasse wie in diesem Blog-Beitrag von Alex Scordellis
Ich habe versucht, die Klasse aus diesem Blog-Beitrag auf mein Problem zu übertragen:
[XmlAttribute("attr")] public NullableInt Value { get; set; }
Der XmlSerializer-Konstruktor schlägt jedoch mit InvalidOperationException fehl:
Mitglied 'Wert' vom Typ TestConsoleApplication.NullableInt kann nicht serialisiert werden.
XmlAttribute / XmlText kann nicht zum Codieren von Typen verwendet werden, die IXmlSerializable implementieren.}
Hässliche Ersatzlösung (schade, dass ich diesen Code hier geschrieben habe :)):
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; } }
Aber ich möchte nicht auf diese Lösung kommen, weil sie die Schnittstelle meiner Klasse für ihre Verbraucher bricht. Ich würde besser IXmlSerializable Schnittstelle manuell implementieren.
Derzeit muss ich IXmlSerializable für die gesamte Element-Klasse implementieren (es ist groß) und es gibt keine einfache Problemumgehung…