Dugggie
Dugggie

Reputation: 366

XML Deserialize returning 0 results in c#

hoping someone can point out what I'm missing here. I'm trying to deserialize the result of a SOAP API call.

I have the following InnerXML within the soapenv:Body of the result

<ns2:OperationResponseInfo xmlns:ns2="http://www.XXXXX.com/webservice/">
    <status>
        <statusCode>0</statusCode>
        <statusDesc>No Error</statusDesc>
    </status>
    <result>
        <record>
            <param>
                <name>totalrecord</name>
                <value>9</value>
            </param>
        </record>
    </result>
    <result>
        <record>
            <param>
                <name>ALARMID</name>
                <value>1581807719208</value>
            </param>
            <param>
                <name>ALARMDESC</name>
                <value>xxxxxxxxxxxxxx</value>
            </param>
            <param>
                <name>ALARMSTATUS</name>
                <value>Unacknowledged</value>
            </param>
        </record>
    </result>
</ns2:OperationResponseInfo>

I am trying to deserialize to the following objects :-

    [XmlRoot(ElementName = "OperationResponseInfo", Namespace = "http://www.XXXXX.com/webservice/")]
    public class OperationResponseInfo
    {
        [XmlElement(ElementName = "status")]
        public Status Status { get; set; }

        [XmlElement(ElementName = "result")]
        public List<Result> Result { get; set; }

        //[XmlAttribute(AttributeName = "ns2", Namespace = "http://www.XXXXX.com/webservice/")]
        //public string Ns2 { get; set; }
    }


    [XmlRoot(ElementName = "status")]
    public class Status
    {
        [XmlElement(ElementName = "statusCode")]
        public string StatusCode { get; set; }

        [XmlElement(ElementName = "statusDesc")]
        public string StatusDesc { get; set; }
    }


    [XmlRoot(ElementName = "result")]
    public class Result
    {
        [XmlElement(ElementName = "record")]
        public List<Record> Record { get; set; }
    }

    [XmlRoot(ElementName = "record")]
    public class Record
    {
        [XmlElement(ElementName = "param")]
        public List<Param> Param { get; set; }
    }

    [XmlRoot(ElementName = "param")]
    public class Param
    {
        [XmlElement(ElementName = "name")]
        public string Name { get; set; }
        [XmlElement(ElementName = "value")]
        public string Value { get; set; }
    }

This is the deserialize method I am using

    public class Serializer
{
    public T Deserialize<T>(string input) where T : class
    {
        System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T));

        using (StringReader sr = new StringReader(input))
        {
            return (T)ser.Deserialize(sr);
        }
    }

and this is the call to the Deserialize method

var alarmList = ser.Deserialize<OperationResponseInfo>(docInner.InnerXml);

I have this working on another system (with different SOAP result format/c# classes etc.) but for some reason the Deserialize is returning 0 results. The code desn't error at all. What am I missing ?

Upvotes: 1

Views: 587

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062855

Namespaces and inheritance rules between xmlns=..., namespace aliases, and what XmlSerializer assumes; try:

    [XmlElement(ElementName = "status", Namespace = "")]
    public Status Status { get; set; }

    [XmlElement(ElementName = "result", Namespace = "")]
    public List<Result> Result { get; set; }

More specifically:

  • when using xmlns="...", namespaces are inherited by descendants
  • when using ns2:blah, that prefix is not inherited by descendants - it must be explicit
  • so <status> and <result> are in the empty namespace
  • but XmlSerializer assumes that namespaces are inherited by default, so [XmlElement(ElementName = "status")] means "an element called status in the same namespace as the current context, i.e. http://www.XXXXX.com/webservice/"
  • so you need to explicitly tell XmlSerializer to go back to the empty namespace

Upvotes: 1

Related Questions