Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# ПІДРУЧНИКИ / c# / Hungry Minds - ASP.NET Bible VB.NET & C#

.pdf
Скачиваний:
127
Добавлен:
12.02.2016
Размер:
7.64 Mб
Скачать

Username and Password. These member variables can be set by applications that wish to pass this data within the SOAP header.

Once you have defined your SOAP header class, you can add it to your Web service implementation and reference it within the method declaration by adding an attribute to that declaration. Although we haven't covered the details of coding Web services and Web service methods, let's take a quick look at the basic syntax involved in this process.

The following code snippet shows the use of our AuthenticationSoapHeader class.

VB.NET:

Public Class MyWebService

Public AuthSoapHeader As AuthenticationSoapHeader

<WebMethod, SoapHeader("AuthSoapHeader")> Public

Function MyWebMethod() As Integer

C#:

public class MyWebService : WebService {

public AuthenticationSoapHeader AuthSoapHeader;

[ WebMethod, SoapHeader("AuthSoapHeader")]

public int MyWebMethod() {

}

}

In this example, we have declared a class named MyWebService that is the implementation class for our Web service. Within this class, we declare a public member variable named AuthSoapHeader, which is an instance of our custom SOAP header class. This class instance is used to set the values contained in the SOAP header.

The next line in our sample decorates the MyWebMethod method declaration with two attributes. The WebMethod attribute indicates that this will be a Web-callable method. The simple addition of this attribute causes ASP.NET to add all the additional features required to make our method callable via the Web. We will examine the WebMethod attribute in much greater detail in subsequent chapters, when we build an ASP.NET Web Service.

Otherwise, our code continues to look and function like a normal class. The SoapHeader attribute is used to specify that a SOAP header should be added to the MyWebMethod method. The parameter of this attribute is used to identify the specific header information to be added to this header and is the name of the member variable we previously declared for our SOAP header instance.

The result of this work is that a SOAP header will be added to the SOAP message that contains two SOAP header elements, the Username and Password. These elements will have values that are specified by the consumer of the Web service.

As we discussed earlier in our coverage of SOAP headers, two attributes named MustUnderstand and DidUnderstand are used with a SOAP header to indicate whether it is mandatory or optional for a recipient to process the header entry. The .NET SoapHeader class implements these SOAP attributes as two Boolean properties of the base class. Therefore, you can set these properties to the desired Boolean value, which will automatically generate the appropriate SOAP attribute when the SOAP message is generated by ASP.NET.

.NET SoapHeader attribute

As we saw in our last example, the SoapHeader attribute is used to enable support for SOAP headers on specific Web service methods that are declared with the WebMethod attribute. Specifically, the SoapHeader attribute is supplied with the name of a member variable that is an instance of our custom SoapHeader class. Technically, this syntax is

setting a property of the SoapHeader attribute, namely the MemberName property. The SoapHeader attribute supports three properties:

§MemberName

§Direction

§Required

The MemberName property of the SoapHeader attribute identifies the name of the class variable that determines the type of the SOAP header. In our example, the type of the SOAP header is obtained from the AuthSoapHeader member variable within the MyWebService class.

The Direction property of the SoapHeader attribute is used to specify in which direction the header is expected to be supplied. By default, SOAP headers are attached to method requests only and are said to be inbound to the Web service. Using this property, we can change this default behavior.

The Direction property accepts an enumeration named SoapHeaderDirection, which supports the three values described in Table 24-4.

Table 24-4: SOAP header direction enumeration

Name

 

Definition

 

 

 

SoapHeaderDirection.In

 

Declares

 

 

that the

 

 

SOAP

 

 

header is

 

 

expected

 

 

to be

 

 

supplied

 

 

to request

 

 

messages

 

 

generated

 

 

by the

 

 

Web

 

 

service

 

 

consumer.

 

 

 

SoapHeaderDirection.Out

 

Declares

 

 

that the

 

 

SOAP

 

 

header is

 

 

expected

 

 

to be

 

 

supplied

 

 

by

 

 

response

 

 

messages

 

 

generated

 

 

by the

 

 

Web

 

 

service.

 

 

 

SoapHeaderDirection.InOut

 

Declares

 

 

that the

 

 

SOAP

 

 

header is

 

 

expected

 

 

to be

 

 

supplied

 

 

by both

 

 

the

 

 

request

 

 

and

 

Table 24-4: SOAP header direction enumeration

 

 

 

 

 

 

 

 

 

Name

 

Definition

 

 

 

 

 

 

 

 

 

response

 

 

 

 

messages

 

 

 

 

.

 

 

 

 

 

 

 

An example of the Direction property is as follows.

 

 

 

 

VB.NET:

 

 

 

 

<SoapHeader("AuthSoapHeader", Direction:=

 

 

 

 

SoapHeaderDirection.Out>

 

 

 

 

C#:

 

 

 

 

[SoapHeader("AuthSoapHeader", Direction=

 

 

 

SoapHeaderDirection.Out]

Finally, the Required property of the SoapHeader attribute is a Boolean property that controls whether or not the SOAP header is required. By default, this property is set to True, which means that if the header is not supplied, a SOAP exception will be raised. Setting this property to False makes the header optional, as in the following example:

VB.NET:

<SoapHeader("AuthSoapHeader", Required:=false)>

C#:

[SoapHeader("AuthSoapHeader", Required=false)]

These are the basics for using SOAP headers in ASP.NET Web Services. Up to this point, however, we have not discussed how a consumer would access the SOAP header to set the values that need to be passed via the SOAP header. Fortunately, these details are handled for us by ASP.NET when the Web service proxy class is created. This makes setting SOAP header values as simple as setting a property on the proxy class instance. You will learn all about Web service proxy classes (the primary means by which a consumer interacts with a Web service) in Chapter 28, "Consuming Web Services."

Now, let's turn our attention to a slightly more advanced feature of ASP.NET, called SOAP extensions.

Using SOAP extensions

One of the more advanced features of SOAP within the .NET Framework is the SOAP extensions technology. Using this technology, you can inspect or modify a SOAP message at specific stages in message processing on either the client (consumer of the Web service) or server (the Web service itself). Of course, this assumes that the client and server are both based on .NET.

SOAP extensions are a powerful feature, because they enable you to implement some very interesting applications that can be leveraged by Web services and/or their clients in a completely transparent manner. For example, you can create extensions that do the following:

§Encrypt messages to protect the contents while in transit

§Compress messages to reduce the size of the transmission stream

§Log messages for auditing or tracing message activity (especially useful in debugging)

§Process SOAP attachments

These are just a few examples of the many other potentially useful applications of this technology.

The .NET Framework exposes this functionality through the following base classes that you can derive from to create custom SOAP extensions:

§System.Web.Services.Protocols.SoapExtension

§System.Web.Services.Protocols.SoapExtensionAttribute

The SoapExtension class is the base class for all SOAP extensions. This class defines a method named ProcessMessage that is called several times at various stages of message processing. These stages are listed in Table 24-5.

Table 24-5: SOAP extension message processing stages

Name

 

Definition

 

 

 

BeforeSerialize

 

During

 

 

SoapClientMessa

 

 

ge processing,

 

 

this stage occurs

 

 

after a client calls

 

 

a Web Service

 

 

method, but prior

 

 

to the call being

 

 

serialized.

 

 

During

 

 

SoapServerMess

 

 

age processing,

 

 

this stage occurs

 

 

after the Web

 

 

Service method

 

 

returns results,

 

 

but prior to those

 

 

results being

 

 

serialized.

 

 

 

AfterSerialize

 

During

 

 

SoapClientMessa

 

 

ge processing,

 

 

this stage occurs

 

 

after a client call

 

 

to a Web Service

 

 

method is

 

 

serialized, but

 

 

prior to the

 

 

network request

 

 

for the call is

 

 

made.

 

 

During

 

 

SoapServerMess

 

 

age processing,

 

 

this stage occurs

 

 

after the results

 

 

for a Web

 

 

Service method

 

 

are serialized, but

 

 

prior to the

 

 

network response

 

 

sending the

 

 

results to the

 

 

client.

 

 

 

BeforeDeserialize

 

During

 

 

SoapClientMessa

 

 

ge processing,

Table 24-5: SOAP extension message processing stages

Name

AfterDeserialize

Definition

this stage occurs after the network response for a Web Service method has been received, but prior to the response being deserialized.

During SoapServerMess age processing, this stage occurs after a network request for a Web Service method is received, but prior to the request being deserialized.

During SoapClientMessa ge processing, this stage occurs after the network response for a Web Service method has been deserialized, but prior to the client receiving the results.

During SoapServerMess age processing, this stage occurs after a network request for a Web Service method is deserialized, but prior to the Web Service method being called.

To create a SOAP extension, you simply derive a class from the SoapExtension class and implement your extension code in the ProcessMessage method. The SOAP message is supplied to you as an input argument to the method. You can examine the SOAP message to determine which stage of message processing is in effect (using the Stage property) and then perform the appropriate processing for that stage.

Note You do not have to implement code for all SOAP extension message stages.

For example, a SOAP extension that is applied to a Web service client could gain access to the SOAP request message at the AfterSerialize stage. To gain access to the SOAP response message, the extension would wait for the BeforeDeserialize stage to occur.

In addition to implementing the SoapExtension class, you must also derive a class from the SoapExtensionAttribute base class. You use this class to create and apply a custom SOAP extension attribute to a method. When the custom extension attribute is added to a Web service method or a proxy class method, the associated extension is invoked at the appropriate time.

So, in summary, to implement a SOAP extension, you must derive classes from the

.NET SoapExtension and SoapExtensionAttribute base classes, and then implement the code in these derived classes to intercept SOAP messages at the message processing stages you are interested in handling.

For specific examples of SOAP extensions, you can refer to the Microsoft .NET online documentation or the Visual Studio online documentation. The MSDN library also contains information about SOAP extensions in the .NET Framework.

Handling SOAP exceptions

As we have previously discussed, SOAP defines a mechanism for Web services to return a SOAP exception message in the face of a failed method call.

Handling SOAP exceptions within .NET applications (including ASP.NET applications) is a simple, straightforward process. The .NET Framework implements a class named SoapException (contained within the System.Web.Services.protocols namespace). The ASP.NET runtime converts SOAP exceptions into instances of the .NET SoapException class. This means that you can use try . . . catch blocks within your calls to Web service methods to catch SOAP exceptions. The following example illustrates how this is done:

VB.NET:

Imports System.Web.Services

Public Class MyWebService

<WebMethod()> Public Function Divide(x as Integer,

y as Integer) as Integer

Return x / y

End Function

End Class

C#:

using System.Web.Services;

public class MyWebService : WebService {

public int Divide(int x, int y) {

return x / y;

}

}

We can catch divide-by-zero exceptions that can occur when calling the Divide Web method by using code similar to the following fragment:

VB.NET:

Dim div As New MyWebService

Dim z as Integer

Try

Z = div.Divide(1, 0)

Catch err As SoapException

strError = "Web method caused an exception"

End Try

C#:

public MyWebService div = new MyWebService;

int z;

try {

z = div.Divide(1,0);

}

catch (Exception e)

{

strError = "Web method caused an exception";

}

The structured exception handling offered by the CLR makes error handling efficient and effective. All we need to do is use try . . . catch blocks to trap errors that may occur in our calls to Web service methods.

Generally speaking, you should always wrap Web service method calls in try . . .

catch blocks. Because Web method calls are at least cross-process (and typically, cross-machine or even cross-network), the possibility always exists that something within the underlying network may go wrong. Unlike local procedure calls that are within a single process, many other factors could cause a remote Web method invocation to fail. So, it's better to be safe than sorry when it comes to recognizing and handling these types of errors.

Microsoft SOAP Toolkit

As you might expect, it is entirely possible to create and consume Web services without the infrastructure and services provided by the .NET Framework and Visual Studio .NET (although it is much easier to do so with their support).

Because Web services are based on XML, HTTP, and SOAP, all we need to create or consume Web services are implementations of these technologies. This is precisely what Microsoft has done with the Microsoft SOAP toolkit.

The Microsoft SOAP toolkit supplies the technologies and tools needed to build and deploy Web services using Visual Studio 6.0 as the development environment along with the familiar COM programming model. In addition to building Web services that can run on Windows NT 4.0 SP6 and Windows 2000, you can build Web service consumers that will run on Windows 98, Windows ME, Windows NT 4.0 SP6, or Windows 2000 SP1.

The toolkit is a free and fully supported SDK that you can download from the MSDN Web site. For those of you who cannot deploy .NET or wish to address legacy platforms with Web services, the Microsoft SOAP Toolkit will prove to be a valuable resource for you.

Although we won't go into great detail about the toolkit here (after all, the subject of this book is ASP.NET), we will briefly discuss the features of the toolkit in case you ever have a need to use it. If that happens, you will want to refer to the documentation that comes with the toolkit for more-detailed information on system requirements, installation instructions, code samples, and the like.

Toolkit features

The toolkit contains both clientand server-side COM components as well as development tools that enable you to build or consume Web services using Visual Studio 6.0 as the development environment. The following are the technologies and tools included in the SOAP toolkit:

§A server-side component that maps Web service requests to COM object method calls described by WSDL and Web Service Meta Language (WSML) documents

§A client-side component that enables a consumer to call Web services described by a WSDL document

§Components that generate, transport, and process SOAP messages

§A WSDL/WSML document -generator tool

§A Visual Basic Add-in that simplifies the processing of XML documents contained in SOAP messages

§Additional APIs, utilities, and sample applications that illustrate how to use the SOAP Toolkit to build Web service and consumer applications

It is worth noting here that Web service consumers created with the SOAP toolkit can invoke any Web service, whether it is based on the SOAP toolkit, ASP.NET, or some other Web service implementation. Likewise, Web services created with the SOAP toolkit can be invoked by any Web service client, regardless of implementation. This illustrates one of the most powerful features of the Web services model that we have discussed previously: implementation independence. The way in which a Web service or Web service consumer is implemented is unimportant so long as they can communicate via XML, HTTP, and SOAP and implement the standards in an equivalent manner.

Let's take a quick look at some of the SOAP Toolkit features that enable you to create Web services and Web service consumers.

Creating a Web service

To enable Web service capabilities on the server, you must first and foremost be able to listen for Web service requests (in other words, SOAP messages) that are delivered to the server. This means that the Web server must be configured to listen for and process Web service request messages.

The SOAP Toolkit provides two choices for providing a SOAP listener for the Internet Information Server (IIS) Web server: an Internet Server API (ISAPI) listener and an Active Server Pages (ASP) listener. Your choice of which listener to use depends on the following:

§In most cases, you can choose the ISAPI listener. The advantages of the ISAPI listener are that it is faster than the ASP listener and does not require you to implement any code. You simply need to supply the WSDL and WSML files that describe the Web service and the mappings to COM server methods. The disadvantage of the ISAPI listener lies in the fact that you have no control over the invocation of Web service methods (this is done automatically).

§If you need to parse or validate input arguments, perform security checks, or execute similar actions on an incoming request, you must use the ASP listener. The advantage of the ASP listener is that you can perform special message processing on the server before invoking the Web service method. The drawbacks of the ASP listener are that it is slower than the ISAPI listener and you must implement custom code in an ASP page to invoke the Web service methods.

After making your choice, you must edit the WSDL document to specify the appropriate URL of the Web service endpoint. For the ASP listener, you should specify the URL to the ASP file. To use the ISAPI listener, you specify the URL to the WSDL file.

If you are using the ISAPI listener, Web service message processing is automatic. When an incoming SOAP request is detected, the ISAPI listener is invoked to handle the message. The ISAPI listener loads the WSDL and WSML files, executes the request, and returns the results in a response message. In this scenario, you only need provide the WSDL and WSML files.

If you are using the ASP listener, you must create an ASP page that uses the SOAPServer COM component to process incoming Web request messages.

Note Both the ISAPI and ASP listeners use the SOAPServer component. So, regardless of listener choice, the SOAP messages are handled identically (once the SOAPServer component receives the request).

The SOAPServer component enables Web service request messages to call methods on COM components. The component exposes several properties and methods that permit an ASP page to pass a Web service request to the component for execution (via the request stream) and supply the results to the caller (via the response stream). Using this component, the ASP page does not have to understand how to process SOAP messages.

To use the SOAPServer component, you specify the WSDL and WSML documents as input arguments to the initialization method. This allows the component to create the mappings between Web service requests and COM method calls.

After you have initialized the SOAPServer object, you can call its invoke method, passing the ASP input stream and output stream as arguments to the method. When you call the invoke method on the SOAPServer object, the following steps occur:

1.The SOAPServer object deserializes the SOAP request message supplied to it via the invoke method.

2.The request is then examined to locate the COM component and method to be called from the WSDL and WSML documents that were loaded when the SOAPServer object was initialized.

3.An instance of the identified COM object is created and the appropriate method is called using the arguments obtained from the request message.

4.The result is obtained from the method call and serialized into a SOAP response message.

5.The SOAP response message is returned to the caller via an output argument of the invoke method.

Creating a Web service consumer

The SOAPClient COM component enables Web service consumers to call Web services. This component leverages the features of the SOAP Toolkit to provide properties and methods that a Web service consumer can use to call Web service methods without having to deal with SOAP messages directly. In this way, the SOAPClient component acts as a proxy object for the Web service.

To use the SOAPClient component, you must have access to the WSDL document that describes the Web service. When you call the initialization method on the component, you pass in the location of the WSDL document. This causes all the operations defined in the WSDL document to be dynamically bound to the SOAPClient component. Once this has been completed, you can invoke the methods defined in the WSDL document via the SOAPClient object.

When you invoke a Web service method bound to the SOAPClient object, the following steps occur:

1.The SOAPClient object serializes the method call into a SOAP request message and delivers it to the server.

2.The server deserializes the SOAP request message and processes the request.

3.The server serializes the result into a SOAP response message and delivers it to the client.

4.The SOAPClient object deserializes the SOAP response message and returns the result to the caller.

5.The SOAPClient object also exposes SOAP fault properties so that you can examine error information in case a method call fails for some reason.

To summarize, the SOAPClient object makes it easy to consume Web services in a COM-like manner. The consumer need only supply the WSDL document that describes the Web service to the SOAPClient object in order to call the operations exposed by the Web service. The SOAPClient object takes care of translating COM method calls into SOAP requests and then translating the SOAP response into a COM method return value. If an error occurs in the method call, the SOAPClient object exposes properties that allow a consumer to gain access to the SOAP fault information that is returned.

WSDL/WSML generator tool

The WSDL/WSML generator tool is used to automatically generate WSDL and WSML documents from COM type libraries. The graphical version of the tool (named Wsdlgen.exe) walks you through the process of generating these documents. It will request the type of listener you wish to use, the location of the COM type library, which methods you wish to expose from the available interfaces in the type library, the folder in which to write the WSDL and WSML documents, and a few other details. After answering these questions, the tool will generate the files for you.

If you wish to script the generation of these files, a command-line version of the tool is also supplied, named Wsdlstb.exe. You can use the /? switch on the command line to get help information on valid command parameters and switches.

The bottom line here is that the WSDL/WSML generator tool can be a great timesaver when preparing your COM components for accessibility as Web services.

SOAP trace utility

One final useful utility to point out that ships with the Microsoft SOAP Toolkit is the SOAP trace utility. Using this graphical utility, you can view SOAP request and response messages transported over HTTP between a Web service and Web service consumer.

The trace utility can be configured to run either on the client or the server. To run the trace utility on the server, you must make a small modification to the WSDL document that specifies the URL to the SOAP endpoint. Once this has been done, you can start the trace utility to begin a tracing session. To run the trace utility on the client, you must copy the WSDL document to the client machine, make a similar modification to the WSDL document, and start the trace utility. After starting the utility, you need to specify the name of the host where the actual Web service is running. After doing so, you will be able to begin a tracing session.

Summary

SOAP is a major element of the Web services infrastructure and a critical factor in the ability of Web services to reach across platforms, operating systems, object models, and programming languages. This greatly increases the interoperability of distributed computing components built on this model.

SOAP extinguishes the language and object model wars by permitting component interoperability at a message level, enabling the user to implement their Web service code in any manner that they wish, using tools and technologies that are familiar and native to the platform on which they work.

Соседние файлы в папке c#