1

Data is returned from an Apache web service, so I am unable to use the Add Service Reference as the generated classes aren't able to make a web service call or return data

I am trying to deserialize the below SOAP response in C# .NET. I can validate that the XDocument statement correctly pulls just the actual response I want to deserialize (taken from this answer), however when I inspect the response object, both Attribute1 and the MapItem list are null.

Any help would be greatly appreciated.

SOAP Response

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <ns1:checkcompanyResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace">
   <checkcompanyReturn xsi:type="ns2:Map" xmlns:ns2="http://xml.apache.org/xml-soap">
    <item xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
     <key xsi:type="soapenc:string">Entry1</key>
     <value xsi:type="soapenc:string">Y</value>
    </item>
    <item>
     <key xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Entry2</key>
     <value xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">N</value>
    </item>
   </checkcompanyReturn>
  </ns1:checkcompanyResponse>
 </soapenv:Body>
</soapenv:Envelope>

C# Classes

[XmlRoot(ElementName = "checkcompanyResponse", Namespace = "http://DefaultNamespace")]
public class CheckCompanyResponse {
    [XmlElement("attribute1")]
    public string Attribute1 { get; set; }
    [XmlArray("checkcompanyReturn")]
    [XmlArrayItem("item")]
    public List<MapItem> Map { get; set; }
}

public class MapItem {
    public string key { get; set; }
    public string value { get; set; }
}

Deserialization code

string fileName = @"C:\Users\SLUKY\Desktop\test.xml";
XDocument document = XDocument.Load(fileName);
XName soapBody = XName.Get("Body", "http://schemas.xmlsoap.org/soap/envelope/");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(CheckCompanyResponse));
CheckCompanyResponse response = (CheckCompanyResponse)xmlSerializer.Deserialize(document.Descendants(soapBody)
    .First()
    .FirstNode
    .CreateReader()
);
Kyle
  • 4,421
  • 22
  • 32

1 Answers1

2

Please Use This Model

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace yournamespace
{
    [XmlRoot(ElementName="key")]
    public class Key {
        [XmlAttribute(AttributeName="type", Namespace="http://www.w3.org/2001/XMLSchema-instance")]
        public string Type { get; set; }
        [XmlText]
        public string Text { get; set; }
        [XmlAttribute(AttributeName="soapenc", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Soapenc { get; set; }
    }

    [XmlRoot(ElementName="value")]
    public class Value {
        [XmlAttribute(AttributeName="type", Namespace="http://www.w3.org/2001/XMLSchema-instance")]
        public string Type { get; set; }
        [XmlText]
        public string Text { get; set; }
        [XmlAttribute(AttributeName="soapenc", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Soapenc { get; set; }
    }

    [XmlRoot(ElementName="item")]
    public class Item {
        [XmlElement(ElementName="key")]
        public Key Key { get; set; }
        [XmlElement(ElementName="value")]
        public Value Value { get; set; }
        [XmlAttribute(AttributeName="soapenc", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Soapenc { get; set; }
    }

    [XmlRoot(ElementName="checkcompanyReturn")]
    public class CheckcompanyReturn {
        [XmlElement(ElementName="item")]
        public List<Item> Item { get; set; }
        [XmlAttribute(AttributeName="type", Namespace="http://www.w3.org/2001/XMLSchema-instance")]
        public string Type { get; set; }
        [XmlAttribute(AttributeName="ns2", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Ns2 { get; set; }
    }

    [XmlRoot(ElementName="checkcompanyResponse", Namespace="http://DefaultNamespace")]
    public class CheckcompanyResponse {
        [XmlElement(ElementName="checkcompanyReturn")]
        public CheckcompanyReturn CheckcompanyReturn { get; set; }
        [XmlAttribute(AttributeName="encodingStyle", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
        public string EncodingStyle { get; set; }
        [XmlAttribute(AttributeName="ns1", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Ns1 { get; set; }
    }

    [XmlRoot(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
    public class Body {
        [XmlElement(ElementName="checkcompanyResponse", Namespace="http://DefaultNamespace")]
        public CheckcompanyResponse CheckcompanyResponse { get; set; }
    }

    [XmlRoot(ElementName="Envelope", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
    public class Envelope {
        [XmlElement(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
        public Body Body { get; set; }
        [XmlAttribute(AttributeName="soapenv", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Soapenv { get; set; }
        [XmlAttribute(AttributeName="xsd", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Xsd { get; set; }
        [XmlAttribute(AttributeName="xsi", Namespace="http://www.w3.org/2000/xmlns/")]
        public string Xsi { get; set; }
    }

}
Hitesh Anshani
  • 1,499
  • 9
  • 19
  • After updating my `XmlSerializer` to be `Envelope response = (Envelope)xmlSerializer.Deserialize(new FileStream(fileName, FileMode.Open))`, the Envelope and Body are deserialized, but `response.Body.CheckcompanyResponse.CheckcompanyReturn` is still `null`. – Kyle Jun 29 '18 at 19:53
  • another thing we can do is using Xpath we can grab values – Hitesh Anshani Jun 29 '18 at 20:10
  • Best Solution for this also is use XSLT to convert Api Response Xml to our Custom XmL format and then Deserialize it – Hitesh Anshani Jun 29 '18 at 20:13
  • 1
    After trying to figure out what was wrong with your code, I used the `Past XML as classes` function which generated a basic skeleton and the `checkcompanyReturn` value is now populated. Thank you for pointing me in the right direction. – Kyle Jun 29 '18 at 20:21