Reputation: 66
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
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