asp.netxmlsoapasmx

Modifying SOAP Header to match 3rd party format


I have to create a web service to retrieve information from a 3rd part company. They have an example of what the soap xml will look like and I have been able to get it to match except for the header part. I have created a webservice.asmx in my asp.net web app to format what they will be sending.

    [WebService(
        Namespace = "",
        Name = "TheRequest")]
    public class WebService1 : WebService
    { 
        public HeaderData HeaderData { get; set; }
        [SoapHeader ("ReplyTo", Required = true)]
        [WebMethod]
        public string TheirRequest(string username, string password, string data)
        {
            if (HeaderData.To == null ||
                HeaderData.ReplyTo.Address == null ||
                HeaderData.MessageID == null ||
                HeaderData.Action == null)
                throw new SoapException("Required information not provided",
                    SoapException.ClientFaultCode);

            if (username.ToLower() == "username" &&
                password.ToLower() == "password")
                return "SUCCESS";
            else
                throw new SoapException("Unrecognized login",
                    SoapException.ClientFaultCode);
        }
    }

    public class HeaderData : SoapHeader
    {
        public string To;
        public ReplyTo ReplyTo { get; set; }
        public string MessageID;
        public string Action;
    }

    public class ReplyTo
    {
        public string Address;
    }

This sets up the xml as below

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="" xmlns:xsd="" xmlns:soap="">
  <soap:Header>
    <HeaderData xmlns="">
      <To>string</To>
      <MessageID>string</MessageID>
      <Action>string</Action>
      <ReplyTo>
        <Address>string</Address>
      </ReplyTo>
    </HeaderData>
  </soap:Header>
  <soap:Body>
    <TheirRequest xmlns="">
      <username>string</username>
      <password>string</password>
      <data>string</data>
    </TheirRequest>
  </soap:Body>
</soap:Envelope>

What they need the call to be formatted to

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="">
    <soapenv:Header xmlns:wsa="">
        <wsa:To>[customer provided URL]</wsa:To>
        <wsa:ReplyTo>
            <wsa:Address>http:...</wsa:Address>
        </wsa:ReplyTo>
        <wsa:MessageID>3DBF4F1510689894919</wsa:MessageID>
        <wsa:Action>urn:submitMessage</wsa:Action>
    </soapenv:Header>
    <soapenv:Body>
        <sub:TheirRequest xmlns:sub="">
            <sub:username>customer_provided_username</sub:username>
            <sub:password>customer_provided_password</sub:password>
            <sub:data>Base64 encoded XML request</sub:data>
        </sub:TheirRequest>
    </soapenv:Body>
</soapenv:Envelope>

There are a few differences:

  1. <soap:Envelope xmlns:xsi="" xmlns:xsd="" xmlns:soap needs to be <soapenv:Envelope xmlns:soapenv
  2. <soap:Header> <HeaderData xmlns=""> needs to be <soapenv:Header xmlns:wsa="">

Is there any way to set this up to match this so we can process their call? or is there any way I can set up the SOAP header to not matter what they send and only care about the body? Any help will be completely appreciated.


Solution

  • I was able to get this to work.

    The first part is that difference #1 doesn't matter. The only part that matters is that the namespace is correct. It doesn't matter how the namespace is named for referencing.

    The second part is that difference #2 doesn't have to be on the header tagline. It can be set to each item in the header. I couldn't find a way to set it to the Header tagline.

    <soap:Header>
      <ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
        <Address>string</Address>
      </ReplyTo>
    </soap:Header>
    

    How this was done was when I declared the SoapHeader field I set the namespace then, individually.

    [XmlRoot(Namespace = "http://www.w3.org/2005/08/addressing")]
    public class ReplyTo : SoapHeader
    {
        public string Address;
    }