Home > database >  XML Deserialize to class
XML Deserialize to class

Time:10-27

I am trying to deserialize an XDocument to a class. I am calling USPS the CityStateLookupResponse API. Every time I deserialize to my class object, the object is always null.

Here is my class

[Serializable()]
[XmlRoot("CityStateLookupResponse", IsNullable = false)]
public class CityStateLookUpResponse
{
    [XmlAttribute("ID")]
    public string Id { get; set; }

    [XmlElement("City")]
    public string City { get; set; }

    [XmlElement("State")]
    public string State { get; set; }

    [XmlElement("Zip5")]
    public string Zip { get; set; }
}

Below is the code I use to call USPS

 XDocument requestDoc = new XDocument(
   new XElement("CityStateLookupRequest",
   new XAttribute("USERID", _postOfficeOptions.UserId),
   new XElement("Revision", "1"),
   new XElement("ZipCode",
     new XAttribute("ID", "0"),
     new XElement("Zip5", zipCode.ToString())
      )
     )
   );
    
try
{
   var url = _postOfficeOptions.Url   requestDoc;
   var client = new WebClient();
   var response = client.DownloadString(url);
    
   var xdoc = XDocument.Parse(response.ToString());
    
   XmlSerializer serializer = new XmlSerializer(typeof(CityStateLookUpResponse));
    
   if (!xdoc.Descendants("ZipCode").Any()) return null;
    
   return (CityStateLookUpResponse)serializer.Deserialize(xdoc.CreateReader());
                       
}
catch (Exception ex)
{
   throw new Exception("In CityStateLookUp:", ex);
}

This line of code always returns null

return (CityStateLookUpResponse)serializer.Deserialize(xdoc.CreateReader());

This is a valid response from the USPS API

<?xml version="1.0"?>
<CityStateLookupResponse><ZipCode ID="0"><Zip5>90210</Zip5>
<City>BEVERLY HILLS</City><State>CA</State></ZipCode>
</CityStateLookupResponse>

Any help would be appreciated

CodePudding user response:

The problem is that you are trying to deserialize starting at the wrong node. The root node for your response is CityStateLookupResponse. That contains a list of ZipCode nodes, and it is the ZipCode nodes that correspond to your current CityStateLookUpResponse class.

You can fix this by changing your response class like this:

[Serializable()]
[XmlRoot("CityStateLookupResponse", IsNullable = false)]
public class CityStateLookupResponse
{
    [XmlElement("ZipCode")]
    public List<ZipCode> ZipCode { get; } = new();
}

[Serializable()]
[XmlRoot("ZipCode", IsNullable = false)]
public class ZipCode
{
    [XmlAttribute("ID")]
    public string Id { get; set; }

    [XmlElement("City")]
    public string City { get; set; }

    [XmlElement("State")]
    public string State { get; set; }

    [XmlElement("Zip5")]
    public string Zip { get; set; }
}
  • Related