Deserialisieren des leeren XML-Attributwerts in die Nullable Int-Eigenschaft mithilfe von XmlSerializer

Bekomme ich eine xml von der 3rd-party und ich brauche deserialisiert werden es in C# - Objekt. Dieses xml kann enthalten Attribute mit Wert vom Typ integer oder leerer Wert: attr="11" oder attr="". Ich möchte Deserialisieren dieses Attribut mit dem Wert in der Eigenschaft mit Typ nullable-integer. Aber XmlSerializer nicht unterstützt Deserialisierung in nullable-Typen. Die folgenden test-code schlägt fehl, während der Erstellung des XmlSerializer mit InvalidOperationException {"Es war ein Fehler reflektieren Typ '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);
    }
}

Wenn ich den Typ 'Value' - Eigenschaft auf int, Deserialisierung schlägt fehl mit InvalidOperationException:

Es ist ein Fehler in XML Dokument (1, 16).

Kann jemand beraten, wie Deserialisieren Attribut mit einem leeren Wert in nullable-Typ (als null) in der gleichen Zeit zu Deserialisieren nicht-leere Attribut-Wert in der integer? Gibt es irgendeinen trick, damit ich nicht zu tun haben Deserialisierung jedes Feld manuell (tatsächlich gibt es eine Menge von Ihnen)?

Update nach dem Kommentar von ahsteele:

  1. Xsi:nil-Attribut

    Soweit ich weiß, wird dieses Attribut funktioniert nur mit XmlElementAttribute - dieses Attribut gibt an, dass das element keinen Inhalt hat, ob child-Elemente oder text. Aber ich muss die Lösung für XmlAttributeAttribute. Trotzdem kann ich nicht ändern, xml, denn ich habe keine Kontrolle über Sie.

  2. bool *Angegebenen-Eigenschaft

    Diese Eigenschaft funktioniert nur, wenn der Attributwert ist nicht leer oder wenn kein Attribut vorhanden ist. Wenn attr hat einen leeren Wert (attr=") die XmlSerializer-Konstruktor fehl (wie erwartet).

    public class Element
    {
        [XmlAttribute("attr")]
        public int Value { get; set; }
    
        [XmlIgnore]
        public bool ValueSpecified;
    }
  3. Benutzerdefinierte Nullable-Klasse, wie in diesem blog-post von Alex Scordellis

    Habe ich versucht zu verabschieden, die die Klasse von diesem blog-post zu meinem problem:

    [XmlAttribute("attr")]
    public NullableInt Value { get; set; } 

    Aber XmlSerializer-Konstruktor scheitert mit InvalidOperationException:

    Nicht serialisieren Mitglied der 'Wert' des Typs TestConsoleApplication.NullableInt.

    XmlAttribute/XmlText kann nicht verwendet werden zum codieren Arten IXmlSerializable implementieren }

  4. Hässlich Surrogat-Lösung (Schande über mich, dass ich schrieb diesen code hier 🙂 ):

    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 will nicht zu kommen mit die Lösung wie diese, weil es bricht Schnittstelle meiner Klasse für seine Verbraucher. Ich würde besser manuell IXmlSerializable-Schnittstelle implementieren.

So wie es derzeit aussieht muss ich IXmlSerializable implementieren für die ganze Element Klasse (es ist groß), und es gibt keine einfache Lösung...

InformationsquelleAutor der Frage Aliaksei Kliuchnikau | 2009-08-18

Schreibe einen Kommentar