Creating and Using SOAP Headers and SOAP Extensions

Now that you understand the basics of creating and using XML Web services, you will learn about two techniques that enable you to add customized behavior: SOAP headers and SOAP extensions. SOAP headers enable you to add custom fields to the Header section of the SOAP messages that are passed back and forth between the client and the web service. SOAP extensions enable you to add custom processing each time a SOAP message is sent or received—for example, you can write code to encrypt your data before it is sent over the Internet and decrypt it on the receiving end.

SOAP Headers

Earlier in this chapter, we discussed the SOAP message format, which consists of the SOAP Envelope, Header, and Body sections. The SOAP Body contains the information about the Web method that you are calling and any parameters that must be passed with the method call. The Header section of the SOAP message typically contains routing information that is used by the web service application when it receives a request. The SOAP specification does not make exact requirements about what items must appear in this section, so you can create customized SOAP headers that are meaningful to your application. A common use of customized SOAP headers is to pass along user identification.

Custom SOAP headers are created by adding a class to your original XML Web services project. This class must inherit from the System.Web.Services.Protocols.SoapHeader class. This class then defines one or more public variables that will become the custom header items. Each Web method in the XML Web service class that will use the custom headers must then be marked with the SoapHeader attribute. The code in your XML Web service would look like Listing 4.6. The bold text shows what we have added to the original web service code.

Listing 4.6: Adding the SoapHeader Class and Attributes to XML Web Service Code

start example
Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Math <WebService(Namespace:="http://tempuri.org/")> _   Public Class Square   Inherits System.Web.Services.WebService   Public custID As UserIDHeader   <WebMethod(Description:="Get the square of a number"), _    SoapHeader("custID", Required:=False)> _       Public Function GetSquare(ByVal inputVal As Double) As Double           Return inputVal * inputVal   End Function   <WebMethod(Description:="Get the square root of a number"), _    SoapHeader("custID", Required:=False)> _       Public Function GetSquareRoot(ByVal inputVal As Double) As Double          Return Sqrt(inputVal)   End Function End Class Public Class UserIDHeader     Inherits SoapHeader     Public userID As String End Class 
end example

Adding the SoapHeader attributes to the XML Web service will change how the WSDL document and the proxy classes are generated. They will also show the attribute, and a public variable, UserIDHeaderValue, will be added to the proxy class, as shown in Listing 4.7. Don’t forget that if you make these changes to the original XML Web services project from Exercise 4.1 and recompile it, you must delete the Web reference from your client project(s) and add them again to regenerate the proxy class with these updates.

Listing 4.7: Additions to the Auto-Generated Proxy Class

start example
 Public UserIDHeaderValue As UserIDHeader <System.Web.Services.Protocols.SoapHeaderAttribute( _   "UserIDHeaderValue", Required:=false)> _   Public Function GetSquare(ByVal inputVal As Double) As Double       Dim results() As Object = Me.Invoke("GetSquare", _           New Object() {inputVal})             Return CType(results(0),Double) End Function
end example

So we have added a class derived from SoapHeader and the SoapHeader attributes to the original XML Web service code. The next step is to modify the client application to provide the value for the custom Header field when calling the Web service method. Listing 4.8 shows the client application code. The lines in bold show the new code that was added to the procedure since Exercise 4.2. First, declare and instantiate a local variable of type UserHeaderID, as defined in our XML Web service. Set the userID property of the object to the desired value. Assign the UserIDHeaderValue property of the Web service Square object to the local object that we just created and populated with values.

Listing 4.8: Setting a Value for the SOAP Header in Client Code

start example
Private Sub btnSquare_Click(ByVal sender As Object, _     ByVal e As System.EventArgs) Handles btnSquare.Click     Dim objSquare As SquareRootService.Square = _         New SquareRootService.Square()     Dim custID As SquareRootService.UserIDHeader = _         New SquareRootService.UserIDHeader()     custID.userID = "X75042"     objSquare.UserIDHeaderValue = custID     Dim inputValue As Double     Dim webResult As Double     inputValue = CType(txtValue.Text, Double)     webResult = objSquare.GetSquare(inputValue)     txtResult.Text = webResult.ToString     objSquare = Nothing End Sub
end example

Finally, let’s add code to the XML Web service to read the user ID that is passed with the method call. In Listing 4.9, the bold lines have been added to access the header information and take appropriate action based on the value that is found. The variable shown here, custID, is the new public variable that was added to the Web service code in Listing 4.6.

Listing 4.9: Modifying the XML Web Service Code to Retrieve the SOAP Header Value

start example
<WebMethod(Description:="Get the square of a number"), _  SoapHeader("custID", Required:=False)> _         Public Function GetSquare(ByVal inputVal As Double) As Double         If custID.userID = "X75042" Then             Return inputVal * inputVal         Else             Return 0         End If     End Function
end example

This technique shows how to pass user information by using custom SOAP headers. This example is intended to demonstrate how to use SOAP headers to pass additional information with your Web service request. By themselves, SOAP headers are not a secure communication, so extra steps to encrypt the user information would be required in a production XML Web service. Security options for XML Web services are discussed in Chapter 9, “Overview of Security Concepts,” and Chapter 11.

In Exercise 4.5, you will create customized SOAP headers by modifying the projects that you completed in Exercises 4.1 and 4.2.

Exercise 4.5: Using Customized SOAP Headers

start example
  1. Open the Visual Studio .NET XML Web service project, called SquareRootService, that you created in Exercise 4.1. Add another Imports statement to the top of the Square.asmx code module:

    Imports System.Web.Services.Protocols
  2. Create a new class in Square.asmx as shown in this code snippet:

    Public Class UserIDHeader     Inherits SoapHeader     Public userID As String End Class
  3. Add the SoapHeader attribute to both of your Web methods as shown:

    <WebMethod(Description:="Get the square of a number"), _  SoapHeader("custID", Required:=False)> _     Public Function GetSquare(ByVal inputVal As Double) As Double

  4. Declare a class-level variable of type UserIDHeader:

    Public custID As UserIDHeader

    Refer to Listing 4.6 to see what the complete code should look like.

  5. Modify the code inside of each Web method to read the custom value:

    <WebMethod(Description:="Get the square of a number"), _  SoapHeader("custID", Required:=False)> _     Public Function GetSquare(ByVal inputVal As Double) As Double         If custID.userID = "X75042" Then             Return inputVal * inputVal         Else             Return 0         End If     End Function

  6. Save your work and build the SquareRootService.

    Now you will modify the Windows client application that you created in Exercise 4.2 to set the value of the custom SOAP header when calling the Web service method.

  7. Open the Visual Studio .NET project, called SquareRootClientProject, that you created in Exercise 4.2.

  8. Delete the existing Web reference to the SquareRootService; then add a reference to the newly modified version. This will cause Visual Studio .NET to generate a new proxy class in your project that contains the SOAP header information.

  9. Add the following code to the btnSquare_Click event procedure, before calling the Web service method. See Listing 4.8 to see what the complete code should look like.

    Dim custID As SquareRootService.UserIDHeader = _     New SquareRootService.UserIDHeader() custID.userID = "X75042" objSquare.UserIDHeaderValue = custID
  10. Save your work and test the client application.

end example

SOAP Extensions

A SOAP extension is a custom procedure that runs a specified stage of SOAP message processing. When a client creates a SOAP request, the data from the client application must be serialized, or written out to the SOAP XML format, so that it can be sent to the Web service over HTTP. You might want to insert a SOAP extension in the AfterSerialize stage of the extension’s SoapExtension.ProcessMessage method to encrypt all application data before sending to the Web service. When the SOAP message reaches the Web service, there is a BeforeDeserialize stage in the extension’s SoapExtension.ProcessMessage method, during which a decryption procedure could be run to decrypt all data. This is an example of when both the client and the XML Web service must each run a SOAP extension in order for the process to work. Also, it’s important to synchronize when your extension processing occurs—if you are doing encryption or compression after serializing the data on one side, make sure you decrypt or decompress before deserializing on the other side. Conversely, if you are selectively encrypting or compressing at the BeforeSerialize stage, the other side of your connection should apply the same selective techniques at the AfterDeserialize stage. Other examples—for example, when you are logging incoming requests to the web service—would require SOAP extensions to be added only at the web server side.

Working with SOAP extensions is similar to the process outlined in the preceding section on SOAP headers. You begin by creating a class that inherits from System.Web.Services.Protocols.SoapExtension. This is where the working code of the extension is located. This class must override methods defined by the SoapExtension base class. These methods are listed here:

GetInitializer This method runs the first time an XML Web service or a particular method is called. Values that are initialized in this procedure are cached and can be used for all future method calls on the service.

Initialize This method is called for every method call to the web service and is automatically passed the data that was stored in cache during the GetInitializer method.

ChainStream This method enables you to store the incoming SOAP message (in a Stream object) and create a new Stream object to hold output from the extension. During subsequent processing of the extension code, you should read data from the incoming stream and write data to the new output stream.

ProcessMessage This method is where you perform the desired processing on the SOAP message. Typically, you will test the Stage property of the incoming message and use conditional logic in the procedure to determine the appropriate action to take. The Stage property will be one of the following: BeforeSerialize, AfterSerialize, BeforeDeserialize, AfterDeserialize.



MCAD/MCSD(c) Visual Basic. NET XML Web Services and Server Components Study Guide
MCAD/MCSD: Visual Basic .NET XML Web Services and Server Components Study Guide
ISBN: 0782141935
EAN: 2147483647
Year: 2005
Pages: 153

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net