Search code examples
c#xmldeserializationdatacontract

How To Properly Deserialize XML Attributes and Arrays?


I'm doing a C# project and I have an object encoded in XML; an example instance would be:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Entity Type="StartRunTestSetResponse">
    <Fields>
        <Field Name="SuccessStaus">
            <Value>2</Value>
        </Field>
        <Field Name="info">
            <Value></Value>
        </Field>
    </Fields>
</Entity>

I need the attribute information because it is a necessity in the Key-Value pairs' the object has.

My deserialization grammar looks like this:

[DataContract(Name="Entity", Namespace="")]
[XmlSerializerFormat]
[KnownType(typeof(SRTSRField))]
[KnownType(typeof(SRTSRValue))]
public class StartRunTestSetResponse
{
    [DataMember(Name="Type"), XmlAttribute("Type")]
    public string type { get; set; }

    [DataMember(Name = "Fields", IsRequired = true), XmlElement("Fields")]
    public List<SRTSRField> fields { get; set; }

    internal StartRunTestSetResponse() { fields = new List<SRTSRField>(); }
}
[DataContract(Name = "Field", Namespace = "")]
[KnownType(typeof(SRTSRValue))]
public class SRTSRField
{
    [DataMember(Name = "Name"), XmlAttribute("Name")]
    public string name {get; set;}

    [DataMember(Name = "Value"), XmlElement("Value")]
    public SRTSRValue value { get; set; }
}
[DataContract(Name = "Value", Namespace = "")]
public class SRTSRValue
{
    [DataMember, XmlText]
    public string value { get; set; }
}

Now, it doesn't work; at the moment it parses down to the Fields element and then any child of it is null.


Solution

  • You can simplify your model

    public class Entity
    {
        [XmlAttribute]
        public string Type { get; set; }
        [XmlArrayItem("Field")]
        public Field[] Fields { get; set; }
    }
    
    public class Field
    {
        [XmlAttribute]
        public string Name { get; set; }
        public string Value { get; set; }
    }
    

    So deserialization would be

    XmlSerializer ser = new XmlSerializer(typeof(Entity));
    using (StringReader sr = new StringReader(xmlstring))
    {
        var entity = (Entity)ser.Deserialize(sr);
    
    }