Earlier in this chapter, you learned the purpose of SOAP headers and the value of using them in the Web service you build. SOAP headers provide an excellent means of adding metadata to a SOAP message. Next, you see that it is relatively simple to add and work with SOAP header blocks in your SOAP messages. You look at how to do so using C# 2.0.
This example uses Visual Studio 2005 to create a C# 2.0 Web service that exposes a simple HelloWorld() method. To start, delete the default .asmx file (Web service file) that comes with the default Web service project. Then, create a new Web service file and name the new .asmx file HelloSoapHeader.asmx. The initial step is to add a class that is an object representing what is to be placed in the SOAP header by the client, as shown in Listing 20-12.
Listing 20-12: A class representing the SOAP header
![]() |
public class HelloHeader : SoapHeader { public string Username; public string Password; }
![]() |
The class, representing a SOAP header object, has to inherit from the .NET Framework SoapHeader class from the System.Web.Services.Protocols namespace. The SoapHeader class serializes the payload of the <soap:header> element into XML for you. In the example in Listing 20-12, you can see that this SOAP header requires two elements-simply a username and a password, both of type String. The names you create in this class are those used for the subelements of the SOAP header construction, so it is important to name them descriptively. Listing 20-13 shows the Web service class that instantiates an instance of the HelloHeader class.
Listing 20-13: A Web service class that utilizes a SOAP header
![]() |
[WebService(Namespace = "http://www.wrox.com/helloworld")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class HelloSoapHeader : System.Web.Services.WebService { public HelloHeader myHeader; [WebMethod] [SoapHeader("myHeader")] public string HelloWorld() { if (myHeader == null) { return "Hello World"; } else { return "Hello " + myHeader.Username + ". " + "<br>Your password is: " + myHeader.Password; } } }
![]() |
The Web service, HelloSoapHeader, has a single method-HelloWorld(). Within the Web service class, but outside of the method itself, you create an instance of the SoapHeader object. This is done with the following line of code:
public HelloHeader myHeader;
Now that you have an instance of the HelloHeader class that you created earlier called myHeader, you can use that instantiation in your method. Because Web services can contain any number of methods, it is not a requirement that all methods use an instantiated SOAP header. You specify whether a method will use a particular instantiation of a SOAP header object by placing the SoapHeader attribute before the method declaration.
[WebMethod] [SoapHeader("myHeader")] public string HelloWorld() { // Code here }
In this example, the SoapHeader attribute takes a string value of the name of the instantiated SoapHeader class-in this case, myHeader.
From here, the method actually makes use of the myHeader object. If the myHeader object is not found (meaning that the client did not send in a SOAP header with his constructed SOAP message), a simple Hello World is returned. However, if values are provided in the SOAP header of the SOAP request, those values are used within the returned string value.
It really isn't difficult to build a consuming application that makes a SOAP request to a Web service using SOAP headers. When using .NET, just as with the Web services that don't include SOAP headers, you need to make a Web Reference to the remote Web service directly in Visual Studio.
For an example of consuming this application using a standard ASP.NET Web page, create a simple .aspx page with a single Label control. The output of the Web service is placed in the Label control. The code for the ASP.NET page is shown in Listing 20-14.
Listing 20-14: An ASP.NET page working with an Web service using SOAP headers
![]() |
<%@ Page Language="C#" %> <script runat="server"> protected void Page_Load(object sender, System.EventArgs e) { localhost.HelloSoapHeader ws = new localhost.HelloSoapHeader(); localhost.HelloHeader wsHeader = new localhost.HelloHeader(); wsHeader.Username = "Bill Evjen"; wsHeader.Password = "Bubbles"; ws.HelloHeaderValue = wsHeader; Label1.Text = ws.HelloWorld(); } </script>
![]() |
Two objects are instantiated. The first is the actual method, HelloWorld(). The second, which is instantiated as wsHeader, is the HelloHeader object. After both of these objects are instantiated and before you make the SOAP request in the application, you construct the SOAP header. This is as easy as assigning values to the Username and Password properties of the wsHeader object. After these properties are assigned, you associate the wsHeader object to the ws object through the use of the HelloHeaderValue property. After you have made the association between the constructed SOAP header object and the actual method object (ws), you can make a SOAP request just as you would normally do:
<lit>Label1.Text = ws.HelloWorld();
Running the page produces a result in the browser as shown in Figure 20-15.
Figure 20-15
What is more interesting, however, is that the SOAP request reveals that the SOAP header was indeed constructed into the overall SOAP message, as shown in Listing 20-15.
Listing 20-15: The SOAP request
![]() |
<?xml version="1.0" encoding="utf-8" ?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <HelloHeader xmlns="http://www.wrox.com/helloworld/"> <Username>Bill Evjen</Username> <Password>Bubbles</Password> </HelloHeader> </soap:Header> <soap:Body> <HelloWorld xmlns="http://www.wrox.com/helloworld/" /> </soap:Body> </soap:Envelope>
![]() |
This returns the SOAP response shown in Listing 20-16.
Listing 20-16: The SOAP response
![]() |
<?xml version="1.0" encoding="utf-8" ?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <HelloWorldResponse xmlns="http://www.wrox.com/helloworld/"> <HelloWorldResult>Hello Bill Evjen.<br>Your password is: Bubbles</HelloWorldResult> </HelloWorldResponse> </soap:Body> </soap:Envelope>
![]() |