Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserializing XML with DataContractSerializer

I have a web service that returns the following data:

<?xml version=""1.0"" encoding=""UTF-8""?>
<RESPONSE>
    <KEY>12345</KEY>
    <PROPERTY>
        <PROPERTY_ADDRESS>
            <STREET_NUM>25</STREET_NUM>
            <STREET_ADDRESS>ELM ST</STREET_ADDRESS>
            <STREET_PREFIX/>
            <STREET_NAME>ELM</STREET_NAME>
            <STREET_TYPE>ST</STREET_TYPE>
            <STREET_SUFFIX/>
        </PROPERTY_ADDRESS>
    </PROPERTY>
</RESPONSE>

I have a class structure to match:

[DataContract(Name="RESPONSE", Namespace="")]
public class Response
{
    [DataMember(Name="KEY")]
    public string Key { get; set; }

    [DataMember(Name = "PROPERTY")]
    public Property Property { get; set; }
}

[DataContract(Name="PROPERTY", Namespace="")]
public class Property
{
    [DataMember(Name="PROPERTY_ADDRESS")]
    public PropertyAddress Address { get; set; }
}


[DataContract(Name="PROPERTY_ADDRESS", Namespace="")]
public class PropertyAddress
{
    [DataMember(Name="STREET_NUM")]
    public string StreetNumber { get; set; }

    [DataMember(Name = "STREET_ADDRESS")]
    public string StreetAddress { get; set; }

    [DataMember(Name = "STREET_PREFIX")]
    public string StreetPrefix { get; set; }

    [DataMember(Name = "STREET_NAME")]
    public string StreetName { get; set; }

    [DataMember(Name = "STREET_TYPE")]
    public string StreetType { get; set; }

    [DataMember(Name = "STREET_SUFFIX")]
    public string StreetSuffix { get; set; }
}

My deserialization code looks like this:

[Test]
public void TestMapping()
{
    var serializer = new DataContractSerializer(typeof(Response));

    Response response = null;

    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(XmlData)))
    {
        response = (Response)serializer.ReadObject(ms);
    }

    //This works
    Assert.AreEqual("12345", response.Key);

    //This works
    Assert.AreEqual("25", response.Property.Address.StreetNumber);

    //This FAILS. StreetAddress is null
    Assert.AreEqual("ELM ST", response.Property.Address.StreetAddress);
}

For the life of me I can't figure out why StreetAddress is failing. It's got to be something simple that I'm missing.

like image 457
Micah Avatar asked Mar 14 '13 15:03

Micah


People also ask

What is Deserializing XML?

Deserialization is the process of reading an instance of an XML document and constructing an object that is strongly typed to the XML Schema (XSD) of the document. Before deserializing, an XmlSerializer must be constructed using the type of the object that is being deserialized.

What is DataContractSerializer and how its different from XMLSerializer?

DataContractSerializer can able to serialize types that implements Idictionary whereas XML serializer not. DataContractSerializer serializes all members which are marked with [DataMember] attribute even if member is marked private. XML serializer serialize only public members.

How do you serialize Datacontract?

To prepare a class for serialization, apply the DataContractAttribute to the class. For each member of the class that returns data that you want to serialize, apply the DataMemberAttribute. You can serialize fields and properties, regardless of accessibility: private, protected, internal, protected internal, or public.

What is serializing and deserializing XML?

Serialization is the process of converting an object into a form that can be readily transported. For example, you can serialize an object and transport it over the Internet using HTTP between a client and a server. On the other end, deserialization reconstructs the object from the stream.


1 Answers

DataContractSerializer expects things to be in alphabetical order. You need to add Order to your Data Members for this to work correctly.

[DataContract(Name = "PROPERTY_ADDRESS", Namespace = "")]
public class PropertyAddress
{
    [DataMember(Name = "STREET_NUM", Order=0)]
    public string StreetNumber { get; set; }

    [DataMember(Name = "STREET_ADDRESS", Order=1)]
    public string StreetAddress { get; set; }

    [DataMember(Name = "STREET_PREFIX", Order=2)]
    public string StreetPrefix { get; set; }

    [DataMember(Name = "STREET_NAME", Order=3)]
    public string StreetName { get; set; }

    [DataMember(Name = "STREET_TYPE", Order=4)]
    public string StreetType { get; set; }

    [DataMember(Name = "STREET_SUFFIX",Order=5)]
    public string StreetSuffix { get; set; }
}
like image 120
vcsjones Avatar answered Oct 23 '22 08:10

vcsjones