Specifying a custom soap header in .NET

Posted by dstanley on December 17, 2006

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 …

Touchscreen Media PC

Posted by dstanley on December 08, 2006

We are thinking we might be able to use something like this with Ellie. Looks really nice.