2016-05-14 2 views
1

У меня есть xml, который возвращается с массивом различных типов объектов. У меня возникают проблемы с xmlchoiceidentifier, когда он попадает в ключевое слово struct. Когда он десериализует его, он просто возвращает null.C# XML десериализация

Вот XML, что я пытаюсь десериализации:

<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> 

Вот код, у меня есть для десериализации:

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

Скопируйте свой xml в меню VS, выберите * Edit/Paste Special/Paste XML как классы *, – Eser

ответ

2

Ваша главная проблема заключается в том, что вы указали [XmlArray("struct"), XmlArrayItem("member")] для public List<ResponseMember> Struct { get; set; }. Это означает, что XML для этой коллекции должен иметь внешний элемент оболочки с именем <struct>. Однако внешний элемент <struct> равен также, указанному атрибутом XmlElement("struct", typeof(ResponseStruct)), на свойстве ResponseMemberValue.Value, но ваш XML имеет только один уровень из <struct> элементов. Таким образом, вам необходимо указать, что эта коллекция не имеет внешний элемент контейнера, используя [XmlElement("member")]. И, хотя ваш XML не содержит образец элемента <array>, я подозреваю, что вы должны сделать то же самое и для ResponseArray.

Далее необходимо указать имя корневого элемента, используя [XmlRoot] или [XmlType]. Если вы используете последний, он будет использоваться автоматически как имя элемента в полиморфном элементе Value.

Таким образом:

[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 
    } 
} 

Прототип fiddle.

Смежные вопросы