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

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

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

Return Me.BeginInvoke("CTemp", New Object() {Temperature, FromUnits, ToUnits}, callback, asyncState)

End Function

<System.Diagnostics.DebuggerStepThroughAttribute()> _ Public Function EndCTemp(ByVal asyncResult

As System.IAsyncResult) As Decimal

Dim results() As Object = Me.EndInvoke(asyncResult)

Return CType(results(0),Decimal)

End Function

End Class

The following proxy class source code generated by the wsdl tool is for C#: //-------------------------------------------------------------------

//<autogenerated>

//This code was generated by a tool.

//Runtime Version: 1.0.2914.16

//

//Changes to this file may cause incorrect behavior and will be lost if

//the code is regenerated.

//</autogenerated>

//-------------------------------------------------------------------

//

// This source code was auto-generated by wsdl, Version=1.0.2914.16.

//

using System.Diagnostics; using System.Xml.Serialization; using System;

using System.Web.Services.Protocols; using System.Web.Services;

[System.Web.Services.WebServiceBindingAttribute(Name="TempConverterSoap",

Namespace="http://tempuri.org/")]

public class TempConverter : System.Web.Services.Protocols.SoapHttpClientProtocol {

[System.Diagnostics.DebuggerStepThroughAttribute()] public TempConverter() {

this.Url = "http://jdc7200cte/ctemp/ctemp.asmx";

}

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("htt p://tempuri.org/CTemp", Use=System.Web.Services.Description. SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols. SoapParameterStyle.Wrapped)]

public System.Decimal CTemp(System.Decimal Temperature, string FromUnits, string ToUnits) {

object[] results = this.Invoke("CTemp", new object[] { Temperature,

FromUnits,

ToUnits});

return ((System.Decimal)(results[0]));

}

[System.Diagnostics.DebuggerStepThroughAttribute()]

public System.IAsyncResult BeginCTemp(System.Decimal Temperature,

string FromUnits, string ToUnits, System.AsyncCallback callback, object asyncState) {

return this.BeginInvoke("CTe mp", new object[] {

Temperature,

FromUnits,

ToUnits}, callback, asyncState);

}

[System.Diagnostics.DebuggerStepThroughAttribute()]

public System.Decimal EndCTemp(System.IAsyncResult asyncResult) {

object[] results = this.EndInvoke(asyncResult);

return ((System.Decimal)(results[0]));

}

}

At this point, you are ready to add the class to your project so that it can be compiled and used to call the methods of the Web service from a consumer application.

Creating a proxy class with Visual Studio

As mentioned previously, Visual Studio automatically creates Web service proxy classes using the Add Web Reference feature. All we need to have is the ability to locate the WSDL document for the Web service. Visual Studio silently takes care of the rest for us, locating the WSDL for a selected Web service, validating the contents, and then generating the proxy class.

Although quite easily the simplest method for obtaining a Web service proxy class, you could also use the wsdl tool in the .NET Framework to accomplish the same thing.

Summary

Finding Web services and generating proxy classes that we can use to consume them is a simple process using the tools built into .NET and Visual Studio. Instead of having to

worry about the implementation details of how to communicate with a Web service, we can interact with the proxy class in an object-oriented fashion and rely on the proxy to handle the details. This greatly simplifies creating applications that consume Web services and permits us to focus on creating the application logic, rather than coding the necessary plumbing.

Now that you have learned of the techniques for creating Web service proxy classes using the wsdl tool, you are ready to create a full-fledged Web service consumer application. We will cover exactly how to do this in the next chapter.

Chapter 28: Consuming Web Services

Overview

In this chapter, you will learn how to write a consumer application for the CTemp Web service that we built in previous chapters.

Many different types of applications can consume Web services, including traditional desktop applications, Web applications, or even other Web services. The example we will build in this chapter will illustrate how to call the CTemp Web service from an ASP.NET Web forms application.

In addition to covering the details of creating Web service consumers, we will take a fairly detailed look at execution flow between our Web service and consumer applications. This will provide you with a good foundational understanding of how Web services work in ASP.NET as well as an appreciation for the great many details related to Web service implementation that are automatically handled on your behalf by the

.NET Framework and the ASP.NET runtime.

Web Service Consumer Overview

A Web service consumer is any application that references and uses a Web service. A Web service consumer can take many forms: a client application, a server application, a component, or even another Web service. The type of the consumer does not matter as long as it has the capability to communicate with Web services using HTTP and SOAP.

To consume a Web service, we must be able to do the following:

§Find the Web service

§Obtain its WSDL service contract

§Generate a proxy class with which to call the Web service

§Create an instance of the proxy class

§Call the methods exposed by the proxy

In previous chapters, we have covered how to find Web services using various tools, including Visual Studio. We have also seen how to obtain the WSDL document and generate a proxy class using the wsdl tool from the .NET Framework SDK as well as Visual Studio's Add Web Reference feature. Armed with this knowledge, we are now ready to create a client application that is capable of calling the methods of any Web service that we can locate and generate a proxy class from.

Web Service Proxies

Recall that communication with a Web service is accomplished via messages that are delivered by a transport protocol. With no assistance from the platform, just to call a Web service, we would have to understand how to create and format SOAP messages as well as how to handle the delivery and receipt of these messages via HTTP.

Ideally, we would like the platform to provide this support for us. Of even greater benefit would be the ability to create an instance of a class that represented the Web service and called the methods, which in turn would carry out the necessary SOAP message generation and transportation activities required to communicate with the actual Web service.

Fortunately, this is exactly what happens when you create a Web service proxy class within the .NET Framework. The proxy class mimics the interfaces of the actual Web service and takes care of formatting appropriate SOAP messages to deliver requests to the Web service as well as process the responses that come back, such that calling a Web service is boiled down to the simple process of calling a method on a .NET class. This makes using Web services easy.

An interesting attribute of ASP.NET Web services is that they can be referenced and called both as a native .NET class and as a Web service. For example, you could build and deploy the CTemp Web service assembly to an application's \bin folder, create an instance of the class, and call its methods directly.

By generating and using a proxy class, however, we can reach our Web service via HTTP and SOAP. The benefit of the proxy class is that we can create an instance of the class and call its methods just like the native .NET assembly. The HTTP and SOAP plumbing required to call Web service methods is completely hidden from us within the proxy class (as it should be).

Why would we want to do this? Simple. We can distribute our Web service to any remote server, and all that we need is XML, HTTP, and SOAP to communicate with it. This greatly broadens the reach of our component to many different platforms, not just Windows platforms.

Let's take a look at the tools and techniques provided by ASP.NET and the .NET Framework to create an ASP.NET Web Forms application to consume our CTemp Web service.

Creating the Consumer Application

In the remaining sections of this chapter, we will build an ASP.NET Web Forms application to illustrate the techniques for consuming a Web service.

The first step in our quest to build a consumer application begins with the creation of a virtual directory on our local Web server to host our application. This process is identical to the process described in Chapter 25, "Building a Web Service," in which we created a Web server virtual directory for our CTemp Web service implementation.

If you don't recall how to create a virtual directory on your local Web server, feel free to refer to the instructions found in Chapter 25. At any rate, you will need a virtual directory named CTempClient that refers to a physical directory located at inetpub\wwwroot\CTempClient, using the same options specified in Chapter 25. When you are finished with this step, you should also create a bin folder that is a child of your Web application folder. This folder will serve as the location for storing our proxy assembly that we will create later in this chapter.

After you have done this, you are ready to begin the process of building your first Web service consumer application. This process begins with the search for the WSDL document that describes the CTemp Web service we wish to consume.

Obtaining the WSDL document

Before we can call methods of the CTemp Web service, we must locate the Web service and obtain information about its message interfaces via the WSDL document. If you have followed the examples in this book, the CTemp Web service was developed on your local Web server and will be found there.

Recall that the disco tool provided in the .NET Framework SDK can be used to locate Web services, given a known server URL. Using this tool, you can locate and copy DISCO and WSDL documents for discovered Web services to your local hard drive.

At this point, we have two choices for obtaining the WSDL document that describes our CTemp Web service. We can use the .NET disco tool or the Internet Explorer Web browser. Each of these methods has specific strengths and weaknesses. Your choice and the level of success you may experience will most likely depend on characteristics of the Web service you wish to consume.

The .NET disco tool is a good choice in the following situations:

§You know at least the URL of the target Web server on which the Web service is deployed.

§Web service discovery has been enabled through the use of one or more DISCO documents on the target Web server.

Internet Explorer is a good choice in the following situations:

§You know the exact URL of the Web service entry point.

§The Web service is an ASP.NET Web service (which implies that it supports discovery of the WSDL document via a properly formatted HTTP request, or obtained via the Web service help page).

§Web service discovery via disco is not possible because no DISCO documents are available for the service.

You may recall that ASP.NET Web services can be queried for such things as the WSDL document via Internet Explorer. You accomplish this by specifying a URL that includes a query string argument targeted at the Web service entry point file. For example, to obtain the WSDL document for our CTemp Web service, we would specify the following URL in the Address bar of our Web browser:

http://localhost/CTemp/CTemp.asmx?WSDL

This returns the WSDL for the CTemp Web service to your browser in XML format. You can then use the File Save As option in Internet Explorer to save the WSDL to a file in your consumer application virtual directory.

Hopefully, you implemented a DISCO document for the CTemp Web service when we covered Web service deployment and publication in Chapter 26. If so, we can use the

.NET disco tool to obtain the WSDL file that is the key to our ability to consume the CTemp Web service.

To obtain the WSDL document for the CTemp Web service using the .NET Framework disco tool, follow these steps:

1.Open a command prompt window.

2.At the command prompt, change the current directory to your Web application folder, as in "cd c:\inetpub\wwwroot\CTempClient," and press Enter.

3.At the command prompt, type "disco http://localhost/ctemp/ctemp.asmx" and press Enter.

Note

If you do not have the path to the .NET Framework SDK in your

default path, you will have to include the complete path to the disco

 

 

tool. By default, the disco tool is located at Program Files\Microsoft

 

.NET\FrameworkSDK\Bin\disco.exe.

Tip

You can type "disco /?" at the command prompt to obtain help on the

command syntax and available options for the disco tool.

 

Figure 28-1 shows the results of executing these commands to obtain the WSDL document for the CTemp Web service on the author's development machine.

Figure 28-1: Obtaining the WSDL document via the disco tool

Executing the disco tool with default options results in the creation of three files in the current directory. Table 28-1 describes these files.

Table 28-1: Files created by the disco tool

File

CTemp.disco

Description

Contains references to the CTemp Web service information that disco discovered at the specified target URL.

CTemp.wsdl

 

The actual

 

 

WSDL

 

 

document

 

 

for the

 

 

CTemp Web

 

 

service.

 

 

 

Results.discomap

 

Catalogs the

 

 

results

 

 

obtained as

 

 

a result of

 

 

executing

 

 

the

 

 

discovery

 

 

process

 

 

against the

 

 

specified

 

 

target URL.

Now that we have the WSDL document, we can create a proxy class that can be used by our consumer application to make method calls on the CTemp Web service.

Of course, if you are using Visual Studio, you can use the Add Web Reference dialog box to locate and create references to Web services. In the specific case of the CTemp Web service, you can use the Web References On Local Web Server link in the Add Web Reference dialog box within Visual Studio to find the CTemp Web service and

automatically create a Web service proxy class that can be used to interact with the service.

Generating the proxy class

The WSDL document that we obtained in the last section describes the capabilities of the CTemp Web service in terms of the data types, inputs, outputs, and message exchange patterns that it supports. In effect, this is a contract between the Web service and the consumer that documents what the Web service will provide and how it will deliver it when supplied with properly constructed messages. It is akin to the Interface Definition Language (IDL) of the RPC and COM technologies in that it describes the functionality of the service in terms of its interfaces (or, in our case, message formats and exchange patterns).

The .NET Framework SDK includes the wsdl tool that we can use to generate proxy classes from these WSDL documents. Using this tool, we can generate an ASP.NET Web service proxy class in any of the supported .NET languages when we supply the tool with a properly formatted WSDL document as input. The proxy class can then be used by our consumer application to make requests against the Web service using a local class that hides all the low-level details of the communication that takes place using HTTP and SOAP.

To generate a proxy class for the CTemp Web service from the WSDL document, follow these steps:

1.Open a command prompt window.

2.At the command prompt, change the current directory to your Web application folder, as in "cd c:\inetpub\wwwroot\CtempClient."

3.At the command prompt, type "wsdl /l:vb /o:CTempProxy.vb /n:CTempProxy CTemp.wsdl" and press Enter.

Tip

You can type "wsdl /?" at the command prompt to obtain help on the

command syntax and available options for the wsdl tool. Not also that

 

 

you must specify the entire path to the wsdl tool if you have not added

 

its path to your PATH environment variable.

Figure 28-2 shows the results of executing these commands to create the CTemp proxy class on the author's development machine.

Figure 28-2: Generating the CTemp proxy class using the wsdl tool

The /l (lowercase L) option specifies the desired source language for the proxy class, such as VB (Visual Basic), CS (C#), or JS (JavaScript). The /o (lowercase O) option specifies the name to be given the proxy class file. If you prefer to use C# for your proxy class, simply substitute CS for VB with the /l option. The /n option specifies the namespace to be assigned to the proxy. This will be useful when we reference the namespace in our client code using ASP.NET's @Import directive.

Before we move on to the next step in writing our Web service consumer application, let's take a brief look at the code that was generated by the wsdl tool for the CTemp proxy class. You can view the proxy class with your favorite text editor.

The following is a partial listing of the CTemp proxy class.

VB.NET:

Imports System

Imports System.Diagnostics

Imports System.Web.Services

Imports System.Web.Services.Protocols

Imports System.Xml.Serialization

'

'This source code was auto-generated by wsdl,

Version=1.0.2914.16.

'

NameSpace CTempProxy

<System.Web.Services.WebServiceBindingAttribute

(Name:="TempConverterSoap", [Namespace]:="http://mydomain.com/CTemp")> _

Public Class TempConverter

Inherits

System.Web.Services.Protocols.SoapHttpClientProtocol

<System.Diagnostics.DebuggerStepThroughAttribute()> _ Public Sub New()

MyBase.New

Me.Url = "http://localhost/CTemp/CTemp.asmx"

End Sub

<System.Diagnostics.DebuggerStepThroughAttribute(), _ System.Web.Services.Protocols.SoapDocumentMethodAttribute

("http://mydomain.com/CTemp/CTemp", RequestNamespace:="http://mydomain.com/

CTemp", ResponseNamespace:="http://mydomain.com/CTemp", Use:=System.Web.

Services.Description.SoapBindingUse.Literal, ParameterStyle:=System.Web.

Services.Protocols.SoapParameterStyle.Wrapped)> _

Public Function CTemp(ByVal Temperature As Decimal, ByVal FromUnits As String, ByVal ToUnits As String) As Decimal

Dim results() As Object = Me.Invoke("CTemp", New Object() {Temperature, FromUnits, ToUnits})

Return CType(results(0),Decimal)

End Function

<System.Diagnostics.DebuggerStepThroughAttribute()> _

Public Function BeginCTemp(ByVal Temperature As Decimal, ByVal

FromUnits As String, ByVal ToUnits As String, ByVal callback As System.AsyncCallback,

ByVal asyncState As Object) As System.IAsyncResult

Return Me.BeginInvoke("CTemp", New Object() {Temperature, FromUnits, ToUnits}, callback, asyncState)

End Function

<System.Diagnostics.DebuggerStepThroughAttribute()> _

Public Function EndCTemp(ByVal asyncResult As System.IAsyncResult) As Decimal

Dim results() As Object = Me.EndInvoke(asyncResult)

Return CType(results(0),Decimal)

End Function

End Class

End Namespace

C#:

Namespace CTempProxy { using System.Diagnostics; using System.Xml.Serialization; using System;

using System.Web.Services.Protocols; using System.Web.Services;

[System.Web.Services.WebServiceBindingAttribute(Name=

"TempConverterSoap",

Namespace="http://mydomain.com/CTemp")]

public class TempConverter :

System.Web.Services.Protocols.SoapHttpClientProtocol {

[System.Diagnostics.DebuggerStepThroughAttribute()]

public TempConverter() {

this.Url = "http://localhost/CTemp/CTemp.asmx";

}

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.Web.Services.Protocols.SoapDocumentMethodAttribute

("http://mydomain.com/CTemp/CTemp",

RequestNamespace="http://mydomain.com/CTemp",

ResponseNamespace="http://mydomain.com/CTemp",

Use=System.Web.Services.Description.

SoapBindingUse.Literal,

ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.

Wrapped)]

public System.Decimal CTemp(System.Decimal Temperature, string

FromUnits, string ToUnits) {

object[] results = this.Invoke("CTemp", new object[] {

Temperature,

FromUnits,

ToUnits});

return ((System.Decimal)(results[0]));

}

[System.Diagnostics.DebuggerStepThroughAttribute()]

public System.IAsyncResult BeginCTemp(System.Decimal Temperature,

string FromUnits, string ToUnits, System.AsyncCallback callback, object asyncState) {

return this.BeginInvoke("CTemp", new object[] {

Temperature,

FromUnits,

ToUnits}, callback, asyncState);

}

[System.Diagnostics.DebuggerStepThroughAttribute()]

public System.Decimal EndCTemp(System.IAsyncResult asyncResult) {

object[] results = this.EndInvoke(asyncResult);

return ((System.Decimal)(results[0]));

}

}

}

Note that the TempConverter proxy class inherits from the .NET class named System.Web.Services.Protocols.SoapHttpClientProtocol, which implies that the TempConverter proxy uses HTTP and SOAP as the communications protocol to invoke the Web service. This is highlighted in the previous code listings.

Now, let's direct our attention to the declaration and implementation of the CTemp method in the code listing. As you can see, the proxy method declaration is identical to the CTemp Web service method, using the name, number, order, and type of arguments. However, the actual implementation is quite different. The proxy class does not perform any conversion of temperature units, as does the actual Web service. Instead, the proxy method contains just two lines of code, as follows.

VB.NET:

Dim results() As Object = Me.Invoke("CTemp", New Object()

{Temperature, FromUnits, ToUnits})

Return CType(results(0),Decimal)

C#:

object[] results = this.Invoke("CTemp", new object[] {

Temperature,

FromUnits,

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