Search code examples
c#xmlserialization

.net core deserialize xml response


I have this xml response as a stream from USPS 3.0 zip code look up api

<ZipCodeLookupResponse>
 <Address ID="1">
 <Address1>Unit 2</Address1>
 <Address2>8 WILDWOOD DR</Address2>
 <City>OLD LYME</City>
 <State>CT</State>
 <Zip5>06371</Zip5>
 </Address>

 <Address ID="2">
 <Address1>Unit 2</Address1>
 <Address2>8 WILDWOOD DR</Address2>
 <City>OLD LYME</City>
 <State>CT</State>
 <Zip5>06371</Zip5>
 </Address>
</ZipCodeLookupResponse>

and I'm trying to deserialize the response in an array of addresses.

[XmlRoot(ElementName = "ZipCodeLookupResponse")]
public class UspsAddress
{
    [XmlArray("Address")]
    public UspsAddressResult[] Addresses {get;set;}
}

[XmlRoot(ElementName = "Address")]
public class UspsAddressResult
{
    [XmlElement(ElementName = "Address2")]
    public string Adress1 { get; set; }
    [XmlElement(ElementName = "Address1")]
    public string Adress2 { get; set; }
    [XmlElement(ElementName = "City")]
    public string City { get; set; }
    [XmlElement(ElementName = "State")]
    public string State { get; set; }
    [XmlElement(ElementName = "Zip5")]
    public string Zip { get; set; }
}

This code is always returning an empty array. How can I fix this code to get both address from the response?

...

    var content = await res.Content.ReadAsStreamAsync();

    var serializer = new XmlSerializer(typeof(UspsAddress));

    var results = (UspsAddress)serializer.Deserialize(content);

Solution

  • Instead of using XmlArray or XmlArrayItem, you can use the `XmlElement`` attribute to set the name of the child elements. The deserializer will recognize that there are multiple elements that are supposed to be deserialized into a list of objects.

    Your class then looks like this:

    [XmlRoot(ElementName = "ZipCodeLookupResponse")]
    public class UspsAddress
    {
        [XmlElement("Address")]
        public UspsAddressResult[] Addresses {get;set;}
    }