AtlSteve
AtlSteve

Reputation: 66

Including another NameSpace in SOAP Envelope in WCF Client

I'm connecting to a Soap1.1 Service. It's a pre-existing service that is using an industry standard interface definition (named MultiSpeak, extremely common in the utility space)

The MultiSpeak standards do not include provisions for passing a CustomerID, which this vendor requires, so they modified the SoapEvenelope slightly. My problem is I cannot figure how to convince WCF to emit the proper XML.

My current Envelope looks like this:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:MultiSpeakMsgHeader UserID="****" Pwd="****" Company="****"
      xmlns="http://www.multispeak.org/Version_3.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:h="http://www.multispeak.org/Version_3.0" />
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetAMRSupportedMeters xmlns="http://www.multispeak.org/Version_3.0" />
  </s:Body>
</s:Envelope>

Here's what I need it to look like to work:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:MultiSpeakMsgHeader UserID="****" Pwd="****" Company="****"
      vendor:CustomerID="StringValue"
      xmlns="http://www.multispeak.org/Version_3.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:h="http://www.multispeak.org/Version_3.0" 
      xmlns:vendor="http://www.MyVendor.com/Multispeak3"/>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetAMRSupportedMeters xmlns="http://www.multispeak.org/Version_3.0" />
  </s:Body>

So there's a new Namespace introduced (My vendor's custom namespace) and onto the existing "MultiSpeakMsgHeader" object, a new property is introduced, called "CustomerID", but the attribute in the XML that represents that property is in a different NameSpace

The WSDL they provided me to work with (standard MultiSPeak WSDL) does not generate this.

I figure it's easy enough to add "CustomerID" as a string property to the MultiSpeakMsgHeader object in reference.cs, but it will not be emitted with the proper xmlns decoration, and thus, will not work (Yes, I tested that...no namespace, no love).

I'm at a loss. I tried tweaking their WSDL and regenerating to make it work, but had no luck.

Any hints, and I would sure be appreciative. I've lost too many hours to this problem already.

Thank you all.

Upvotes: 0

Views: 1477

Answers (1)

Rajesh
Rajesh

Reputation: 7886

You can try to build your own soap header. Some sample code is below:

using (OperationContextScope scope = new OperationContextScope(objService.InnerChannel))

        {
            UsernameToken objUsernameToken = new UsernameToken() { Username = "rajesh", Password = "rajesh" };
            List<Type> obj = new List<Type>();
            obj.Add(typeof(UsernameToken));

            //XmlObjectSerializer ser = new DataContractSerializer(typeof(Security), "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", obj);

            XmlObjectSerializer ser = new CustomXmlSerializer(typeof(Security), "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            Security security = new Security();
            security.UsernameToken = objUsernameToken;

            MessageHeader header = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
                                                              security, ser, false);

            OperationContext.Current.OutgoingMessageHeaders.Add(header);

            try
            {   
                //Would get a exception but the response was successful. You can see that in fiddler. 
                //The cause for the exception is that the response has the security elements mustUnderstand set to 1 chagning that to 0 would resolve the problem. Need to find on how to do that
                string response = objService.GetInformation();
            }
            catch (Exception ex)
            {
                OperationContext.Current.IncomingMessageHeaders.RemoveAll("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");   
                //throw;
            }

        } 

Hope you can chagne the code above to suit your requirements.

Upvotes: 1

Related Questions