2016-05-14 10 views
1

Ich habe XML, die mit einem Array von verschiedenen Arten von Objekten zurückgegeben wird. Ich habe Probleme mit dem xmlchoiceidentifier, wenn es zum Schlüsselwort struct kommt. Wenn es es deserialisiert, gibt es nur null zurück. HierC# XML-Deserialisierung

ist die xml, die ich deserialisieren versuche:

<struct> 
    <member> 
     <name>result</name> 
     <value><boolean>1</boolean></value> 
    </member> 
    <member> 
     <name>user_info</name> 
     <value> 
     <struct> 
      <member> 
       <name>First Name</name> 
       <value><string>John</string></value> 
      </member> 
      <member> 
       <name>Last Name</name> 
       <value><string>Smith</string></value> 
      </member> 
     </struct> 
     </value> 
    </member> 
</struct> 

Hier ist der Code ich für die Deserialisierung haben:

public class ResponseStruct 
{ 
    [XmlArray("struct"), XmlArrayItem("member")] 
    public List<ResponseMember> Struct { get; set; } 
} 

public class ResponseArray 
{ 
    [XmlArray("array"), XmlArrayItem("data")] 
    public List<ResponseMemberValue> Array { get; set; } 
} 

public class ResponseMember 
{ 
    [XmlElement("name")] 
    public string Name { get; set; } 

    [XmlElement("value")] 
    public ResponseMemberValue Value { get; set; } 
} 

public class ResponseMemberValue 
{ 
    [XmlChoiceIdentifier("ValueChoice"), XmlElement("boolean", typeof(bool)), XmlElement("int", typeof(int)), XmlElement("string", typeof(string)), XmlElement("datetime", typeof(DateTime)), XmlElement("double", typeof(double)), XmlElement("base64", typeof(string)), XmlElement("array", typeof(ResponseArray)), XmlElement("struct", typeof(ResponseStruct))] 
    public object Value { get; set; } 

    [XmlIgnore] 
    public virtual ValueType ValueChoice { get; set; } 

    public enum ValueType 
    { 
     @string, 
     @int, 
     @datetime, 
     @double, 
     base64, 
     array, 
     boolean, 
     @struct 
    } 
} 
+2

Kopieren Sie Ihre XML, wählen Sie in Ihrem VS-Menü * Bearbeiten/Inhalte einfügen/XML als Klassen einfügen *, – Eser

Antwort

2

Ihr Hauptproblem ist, dass Sie [XmlArray("struct"), XmlArrayItem("member")] für public List<ResponseMember> Struct { get; set; } angegeben haben. Dies bedeutet, dass das XML für diese Auflistung ein äußeres Wrapperelement mit dem Namen <struct> haben sollte. Ein äußeres <struct>-Element ist jedoch und, das durch das XmlElement("struct", typeof(ResponseStruct))-Attribut auf der enthaltenden ResponseMemberValue.Value -Eigenschaft angegeben wird - aber Ihr XML hat nur eine Ebene <struct> Elemente. Daher müssen Sie angeben, dass diese Sammlung nicht ein äußeres Containerelement aufweist, indem Sie [XmlElement("member")] verwenden. Und während Ihr XML kein Beispiel des Elements <array> enthält, vermute ich, dass Sie das gleiche für ResponseArray auch tun sollten.

Als nächstes müssen Sie den Namen des Stammelements mit [XmlRoot] oder [XmlType] angeben. Wenn Sie Letzteres verwenden, wird es automatisch als Elementname im polymorphen Value Element verwendet.

So:

[XmlType("struct")] 
public class ResponseStruct 
{ 
    [XmlElement("member")] 
    public List<ResponseMember> Struct { get; set; } 
} 

[XmlType("array")] 
public class ResponseArray 
{ 
    [XmlElement("data")] 
    public List<ResponseMemberValue> Array { get; set; } 
} 

public class ResponseMember 
{ 
    [XmlElement("name")] 
    public string Name { get; set; } 

    [XmlElement("value")] 
    public ResponseMemberValue Value { get; set; } 
} 

public class ResponseMemberValue 
{ 
    [XmlChoiceIdentifier("ValueChoice")] 
    [XmlElement("boolean", typeof(bool)), 
    XmlElement("int", typeof(int)), 
    XmlElement("string", typeof(string)), 
    XmlElement("datetime", typeof(DateTime)), 
    XmlElement("double", typeof(double)), 
    XmlElement("base64", typeof(string)), 
    XmlElement(typeof(ResponseArray)), 
    XmlElement(typeof(ResponseStruct))] 
    public object Value { get; set; } 

    [XmlIgnore] 
    public virtual ValueType ValueChoice { get; set; } 

    public enum ValueType 
    { 
     @string, 
     @int, 
     @datetime, 
     @double, 
     base64, 
     array, 
     boolean, 
     @struct 
    } 
} 

Prototype fiddle.