Search code examples
c#xmlserialization

Deserializing XML doesn't work for one field


I'm trying to deserialize an XML stream into an object. It works perfectly for all but one field and I can't figure out what is wrong with that field. To make sure I know what I'm dealing with, I've coded the XML string directly.

[DataContract(Name = "auth")]
public class Authorization
{
    [DataMember(Name = "status")]
    public string Status { get; set; }
    [DataMember(Name = "user_name")]
    public string UserName { get; set; }
    [DataMember(Name = "person_pk")]
    public string PersonID { get; set; }
}

StringBuilder sb = new StringBuilder();
sb.Append("<auth xmlns=\"http://schemas.datacontract.org/2004/07/Veracross\">");
sb.Append("<status>success</status>");
sb.Append("<person_pk>2516</person_pk>");
sb.Append("<user_name>scohen</user_name>");
sb.Append("</auth>");

string fixedXMLData = sb.ToString();

DataContractSerializer serializer = new DataContractSerializer(typeof(Authorization));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(fixedXMLData));
Authorization Auth = (Authorization)serializer.ReadObject(stream);

When I test the Auth object after execution I find that Status and UserName are properly populated. PersonID is null. I've tried changing the field names in the XML string, reordering the fields, changing the content of the person_pk field, etc. Nothing makes it work.

Now here's where it gets weird - If I change "person_pk" to "test" everywhere, it works fine and I get the correct value for PersonID. However, if I swap "person_pk" for "person" or "pk" it still doesn't work? In reality, I'm getting this XML string from a RESTful service and have no control over the naming of the fields. The field is named "person_pk", I just can't figure out why it won't properly deserialize.

Any idea?

Thanks


Solution

  • Change the order of fields in XML file so that person_pk comes before status:

    sb.Append("<auth xmlns=\"http://schemas.datacontract.org/2004/07/Veracross\">");
    sb.Append("<person_pk>2516</person_pk>");
    sb.Append("<status>success</status>");
    sb.Append("<user_name>scohen</user_name>");
    sb.Append("</auth>");
    

    DataSerializer considers the fields order too.

    UPDATE: You may be interested in this discussion: Ignore field order in DataContractSerializer