Today I was doing some interop testing between a .NET client and a backend Artix* SOAP/HTTP server that requires a custom soap header [* I work for IONA].
Defining the header via wsdl
Theres a couple of different ways to define the soap header. In this case I defined the type for the custom soap header explicitly in the web service contract.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<types> ... <complexType name="SOAPHeaderData"> <sequence> <element name="originator" type="xsd:string"/> <element name="message" type="xsd:string"/> </sequence> </complexType> <element name="SOAPHeaderInfo" type="tns:SOAPHeaderData"/> ... </types> |
A message part was defined for the SOAPHeaderInfo element.
1 2 3 4 |
<message name="header_message"> <part element="tns:SOAPHeaderInfo" name="header_info"/> </message> |
The header was added to the binding
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<binding name="Greeter_SOAPBinding" type="tns:Greeter"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sayHi"> <soap:operation soapAction="" style="document"/> <input name="sayHiRequest"> <soap:body use="literal"/> <soap:header message="tns:header_message" part="header_info" use="literal"/> </input> <output name="sayHiResponse"> <soap:body use="literal"/> <soap:header message="tns:header_message" part="header_info" use="literal"/> </output> </operation> </binding> |
.NET client
On the client side I started with a boilerplate C# console application.
In order to populate client requests with the custom header and invoke on the server:
1.In the Visual Studio project navigator, right click to add a “Web Reference”
2.In the WebReference wizard, specify a file path to the wsdl and click “Go”.
3.The wizard should detect the methods in your wsdl. Specify a name for the proxy and click finish.
4.In the code, as we added the header to the binding, .NET creates a placeholder where you can set the header.
5.I set the header as shown in the following code:
1 2 3 4 5 6 7 8 9 10 |
SOAPHeader.SOAPService service = new SOAPHeader.SOAPService();
SOAPHeader.SOAPHeaderData header = new SOAPHeader.SOAPHeaderData();
header.message="test soap header message";
header.originator="dave.stanley";
service.SOAPHeaderInfo = header;
service.greetMe("test");
|
The message that goes over the wire looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version='1.0' encoding='utf-8'?> <SOAP-ENV:Envelope xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:m1="http://www.iona.com/soap_header" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header> <m1:SOAPHeaderInfo SOAP-ENV:mustUnderstand="1"> <originator>dave.stanley</originator> <message>test soap header message</message> </m1:SOAPHeaderInfo> </SOAP-ENV:Header> <SOAP-ENV:Body> <m1:requestType>me</m1:requestType> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
Next is the https interop …