1

I have xml that is returned with an array of different types of objects. I am having trouble with the xmlchoiceidentifier when it gets to the keyword struct. When it deserializes it, it just returns null.

Here is the xml that I am trying to deserialize:

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

Here is the code I have for deserialization:

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
    }
}
1
  • 2
    Copy your xml, in your VS menu, chose Edit / Paste Special / Paste XML as Classes, Commented May 14, 2016 at 16:39

1 Answer 1

2

Your main problem is that you have specified [XmlArray("struct"), XmlArrayItem("member")] for public List<ResponseMember> Struct { get; set; }. This means that the XML for this collection should have an outer wrapper element named <struct>. However, an outer <struct> element is also specified by the XmlElement("struct", typeof(ResponseStruct)) attribute on the containing ResponseMemberValue.Value property - but your XML has only one level of <struct> elements. Thus you need to specify that this collection does not have an outer container element, by using [XmlElement("member")]. And, while your XML does not include a sample of the <array> element, I suspect you should do the same for ResponseArray also.

Next, you need to specify the root element name using [XmlRoot] or [XmlType]. If you use the latter, it will be used automatically as the element name in the polymorphic Value element.

Thus:

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.