Building Web Service Proxies


A proxy works on behalf of others. A good example is proxy web server software. Users configure their web browser to use a proxy server and make requests for Internet resources (such as http://msdn.microsoft.com/) to the proxy. The proxy then makes a request on the behalf of the browser to the requested URL.

Note

You can use proxy classes to represent the web service you want to call.

In the previous chapter, we created a Fibonacci class that supports a single method called GetSeqNumber . The class was compiled into a .NET assembly and deployed to an ASP.NET application's \bin directory (on the server).

This assembly can be used as both a web service and a local class inside an ASP.NET page. For example, you could write the following ASP.NET page (using VB.NET):

  <script runat="server">     Public Sub Page_Load(sender As Object, e As EventArgs)   Dim fibonacci As New Fibonacci()   result.Text = Fibonacci.GetSeqNumber(5)   End Sub     </script>     Index of 5 in the Fibonacci Series is:   <asp:literal id="result" runat="server"/>  

However, this class was implemented as a web service as well, which means that you also have the ability to call the GetSeqNumber method via SOAP over a network.

The question is can we expect applications that wish to use our Fibonacci Web service to work with the raw SOAP messages (the HTTP and XML) directly? Probably not! Consumers of our web service should not have to formulate their own XML messages, and then encapsulate those messages in HTTP in order to send them to the appropriate destination. The same is true for receiving messages. Consumers should use a proxy representation of the web service.

Fibonacci Proxy

The WSDL describes the web service and you can create a .NET class using tools that are capable of reading and parsing the WSDL. For example, you can build a proxy class for the Fibonacci Web service that will have a class named Fibonacci and a GetSeqNumber method.

The proxy class does not contain the actual implementation (the code that calculates the sequence number), since this is not described in the WSDL. The implementation still resides within the called web service. However, programmatically the proxy has the same public methods . Its classname, method names , and parameters are the same as those for a local Fibonacci class, but the methods wrap calls to the remote Fibonacci Web service. As an example, consider the VB.NET pseudocode for a proxy implementation of Fibonacci :

  Public Class Fibonacci   Inherits SoapHttpClientProtocol     Public Sub New()   MyBase.New   Me.Url = "http://[Server]/Fibonacci_cs.asmx"   End Sub     Public Function GetSeqNumber(ByVal fibIndex As Integer) As Integer   Dim results() As Object = Me.Invoke("GetSeqNumber", _   New Object() {fibIndex})   Return CType(results(0),Integer)   End Function     End Class  

This pseudocode contains a class named Fibonacci and a single GetSeqNumber function.

The proxy function name and parameters look identical to the web service implementation, but the actual implementation (highlighted) is obviously different. Here we have two lines of code. The first line uses the Invoke function to call the web service and return a result. The second line uses the VB.NET CType function to cast the return data, results(0) , to an Integer type:

 Public Function GetSeqNumber(ByVal fibIndex As Integer) As Integer  Dim results() As Object = Me.Invoke("GetSeqNumber", _   New Object() {fibIndex})   Return CType(results(0),Integer)  End Function 

Let's expand this a little further. Imagine if the Fibonacci Web service was implemented on a server residing in New York, while the application that wished to call it was in Seattle. The Seattle application could examine the WSDL of the New York Fibonacci Web service and construct a proxy class similar to the preceding example. The application could then write an ASP.NET page that, when requested, would use the local proxy to call the Fibonacci Web service in New York. The New York Web service would then perform the work and return the result to the application in Seattle that called it:

click to expand
Figure 20-1:

The ASP.NET page that uses the Fibonacci proxy might look as follows (written using VB.NET):

  ' Seattle ASP.NET application   <script runat="server">   Public Sub Page_Load(sender As Object, e As EventArgs)   Dim fibonacci As New Fibonacci()   lblResult = Fibonacci.GetSeqNumber(5)   End Sub   </script>   Index of 5 in the Fibonacci Series is:   <asp:label id="lblResult" runat="server"/>  

To the Seattle developer who is coding the application, it appears as if Fibonacci is a local class, when in fact the class is a proxy of the New York Web service.

Now that we know what a proxy is used for, let's discuss how to automate its creation.

Creating Proxy Classes

There are four ways to create proxies for web services:

  • Use Visual Studio .NET and add a Web Reference to a new project.

  • Use the wsdl.exe command-line utility available with the .NET Framework SDK.

  • Use the Microsoft SOAP toolkit.

  • As long as the platform is capable of sending and receiving HTTP and is capable of parsing strings (or supports XML), you've got everything necessary for communicating with a web service, so you could roll your own using the technology of your choice.

    Note

    Although all the examples in this chapter use ASP.NET Web services, the .NET technology used for creating the proxies could be applied to any web service so long as it uses SOAP.

Because this book is about .NET, we'll focus only on the first two options for building proxies: Visual Stuido.NET and the wsdl.exe command-line tool. However, using Visual Studio .NET is by far the easiest method available.

Let's start by looking at how we build a proxy using Visual Studio .NET. After we use Visual Studio .NET and the command-line tool to build and use a proxy, we'll come back and examine the auto-generated proxy class in more detail. For both examples we'll use the Fibonacci Web service created in the previous chapter.

Using Visual Studio .NET

If you've built an application using Visual Basic 6, you're probably familiar with the Add Reference option, available from any VB project under Project Add Reference, which allowed for referencing a component you wanted to include in your project.

Including a reference allows you to early-bind to the object, instead of late-binding. Early binding simply allows you to know the data types at both runtime and compile-time, while late binding would force the code to determine the data types at runtime. For example, late-bound code would be as follows (this code is written in Visual Basic 6 and so makes use of the Object data type):

  Dim objAdo As Object   Set objAdo = CreateObject("ADODB.Connection")  

With late-bound code, an instance of ADODB.Connection would be treated as an Object type, and VB would be responsible for calling the appropriate methods at runtime. Late-binding is expensive, and we want to avoid it where possible.

Instead of writing late-bound code, you could use the Add Reference option in VB to add a reference at design-time. The code would then become:

  Dim objAdo As New ADODB.Connection  

VB would treat objAdo as an instance of type ADODB.Connection at runtime.

Visual Studio .NET continues to support the concepts of early and late binding, as well as the Project Add Reference option. However, there's a new option specifically designed for web services: Project Add Web Reference.

Add Web Reference

Visual Studio .NET supports the capability to early-bind to web services.

When you add a Web Reference to a Visual Studio .NET project (the Add Web Reference option is available to all Visual Studio .NET projects and languages), Visual Studio .NET will do all the work required to connect to the web service, parse the WSDL, and will generate a proxy class that you can use.

Using the Fibonacci Web Service

Let's look at an example using our Fibonacci Web service. Before you can create the Web Reference, you need to know the location of the WSDL for referencing the web service. For example, the address of the WSDL for the VB.NET Fibonacci implementation of the ASP.NET Web service on my server is http://localhost/WebServices/Fibonacci_vb.asmx?WSDL.

Next, let's create a new Visual Studio .NET project. Since this book is about ASP.NET, we'll create a new ASP.NET Web application using Visual Basic .NET as the language. Once Visual Studio .NET creates the new application, you're presented with a design page. You can drag-and-drop elements onto this page. For this example, you'll need a textbox, a label, and a button, as shown in Figure 20-2:

click to expand
Figure 20-2:

Leave the names of each of these items the same, that is, TextBox1 , Button1 , and Label1 . Now you're ready to add the Web Reference.

You have two options: you can either select Project Add Web Reference or you can right-click on the References in the Solution Explorer and select Add Web Reference. Both open the Add Web Reference dialog box shown in Figure 20-3:

click to expand
Figure 20-3:

Within this dialog box, you can browse services provided by UDDI (the link to Microsoft UDDI takes you to the Microsoft UDDI implementation), browse Web References on the Local Web Server (for web services created with Visual Studio .NET), or enter the address.

Enter the address of the Fibonacci Web service, as shown in Figure 20-4:

click to expand
Figure 20-4:

On the left-hand side of the Add Web Reference dialog, you can view the WSDL. Essentially Visual Studio .NET has fetched the WSDL from the specified location, and has validated it. The Add Reference button is now enabled and we are able to add a reference to the web service described by this WSDL to the current project (at which point Visual Studio .NET will create a proxy).

Click on Add Reference. Visual Studio .NET will create a new section in the Solution Explorer entitled Web References. Behind the scenes, Visual Studio .NET has parsed the WSDL, created a proxy object that represents the web service (the namespace of the proxy is the name of the server the WSDL was served from, which is localhost in this case), and cached a local copy of the WSDL. This is all visible if you expand the Web References section with the Solution Explorer shown in Figure 20-5:

click to expand
Figure 20-5:

You can now write code in the web application to use the Fibonacci Web service. Double-click on Button1 and write some code for the Button1 _ Click event handler. Once the code view is open, write the following to call the GetSeqNumber of the Fibonacci Web service:

 Private Sub Button1_Click(ByVal sender As System.Object,                           ByVal e As System.EventArgs) Handles Button1.Click  Dim fibonacci As New localhost.Fibonacci()    Dim indexIntoSeries As Integer         indexIntoSeries = TextBox1.Text         Label1.Text = fibonacci.GetSeqNumber(indexIntoSeries)  End Sub 

We first create an instance of the proxy, fibonacci , by calling New localhost.Fibonacci .

Note

Changing the namespace in this example from localhost to some more meaningful value, such as MathServices, is as simple as right-clicking on localhost in the Solution Explorer and selecting rename.

Next, we declare a local variable, indexIntoSeries . This is used as the parameter value for the call to GetSeqNumber . The value from TextBox1 is extracted and assigned to indexIntoSeries “so the user must enter an Integer value. We then use our instance, fibonacci , calling the GetSeqNumber method and passing in the value of indexIntoSeries . When the call completes, an Integer is returned, the value of which is assigned to Label1.Text .

Here's a high-level rundown of what occurs when you run this application and click on Button1 :

  1. ASP.NET creates an instance of the proxy and calls it, passing in the value of TextBox1 .

  2. The proxy calls the Fibonacci Web service via SOAP, which computes the result and sends it back to the proxy via SOAP.

  3. The proxy then deserializes the SOAP message (converts the values within the SOAP message to .NET types) and returns an Integer value, which is displayed to the end user.

Let's take a look at the sourcecode that Visual Studio .NET created.

Viewing the Source for the Proxy

Visual Studio .NET has obviously done a lot of work for us “it's created the proxy that can send and receive the SOAP requests and responses.

You can access and modify the sourcecode that Visual Studio .NET creates and compiles for the proxy. It's not available by default, but if you right-click on the project in Solution Explorer and select Add Existing Item, a file selection dialog box is opened. The file dialog box is currently accessing the root directory of the project. You should see a folder named localhost (or another name if you renamed the Web Reference). If you open this folder, you'll find the source to your proxy. On my server, the source file is Fibonacci_cs.vb (Figure 20-6):

click to expand
Figure 20-6:
Note

The proxy is created in the language the project is using. For this particular example, the proxy source is in VB.NET, as we'd created a VB.NET ASP.NET Web application.

If you open this source file, it'll be added to your current project and you can view or modify its source.

Creating a proxy using Visual Studio .NET is simple. As long as you have the URL to the WSDL, Visual Studio .NET can take care of the rest. You can write code and call methods just as you would expect to with a local class, when in fact the proxy is exchanging SOAP messages with a web service.

While Visual Studio .NET definitely makes using web services easy, it isn't required for creating proxy classes. If you're using .NET, but don't have a copy of Visual Studio .NET, you can still automate the process of building proxies to web services using the wsdl.exe command-line tool.

Using wsdl.exe

The wsdl.exe command-line tool is installed by the .NET Framework and used to generate proxy classes from WSDL contracts. Using wsdl.exe to generate a proxy for a .NET application isn't as easy as it is with Visual Studio .NET. For example, the output of wsdl.exe is always a source file, which then has to be compiled. However, the command-line tool gives you more options, such as the language (which can be any .NET language) that should be used for the proxy source file.

Creating the Source File

Let's start by using wsdl.exe to generate a proxy for a WSDL document available at http://localhost/wrox/4885/WebServices/Expose/Fibonacci/Fibonacci_cs.asmx?WSDL. At the command prompt, run the following command:

  wsdl http://localhost/.../Fibonacci_cs.asmx?WSDL  

The result is a source file (by default written in C#) named Fibonacci.cs .

By default, if you name an HTTP-based WSDL location, wsdl.exe will use the proxy settings configured for Internet Explorer. Alternatively, you can copy the WSDL locally and then run it through wsdl.exe :

  wsdl Fibonacci_vb.wsdl  

The result is the same “ a C# source file that represents the proxy. The language is configurable, and to generate the proxy in VB.NET, you simply need to set the language flag:

  wsdl /language:VB http://localhost/.../Fibonacci_cs.asmx?WSDL  

When you open up the source files, you are presented with similar implementations that differ in language. The VB.NET file contains:

 Option Strict Off Option Explicit On      Imports System Imports System.ComponentModel Imports System.Diagnostics Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Xml.Serialization      <System.Diagnostics.DebuggerStepThroughAttribute(), _ System.ComponentModel.DesignerCategoryAttribute("code"), _ System.Web.Services.WebServiceBindingAttribute(Name:="FibonacciSoap", [Namespace]:="http://tempuri.org/")> _ Public Class Fibonacci    Inherits System.Web.Services.Protocols.SoapHttpClientProtocol         Public Sub New()       MyBase.New       Me.Url = "http://localhost/WebServices/Fibonacci_vb.asmx"    End Sub      <System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Get SeqNumber", RequestNamespace:="http://tempuri.org/", ResponseNamespace:="http://tempuri.org/", Use:=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle:=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)>    Public Function GetSeqNumber(ByVal fibIndex As Integer) As Integer       Dim results() As Object = Me.Invoke("GetSeqNumber", New Object()                      {fibIndex})       Return CType(results(0),Integer)    End Function         Public Function BeginGetSeqNumber(ByVal fibIndex As Integer, ByVal callback As System.AsyncCallback, ByVal asyncState As Object) As System.IAsyncResult       Return Me.BeginInvoke("GetSeqNumber", New Object() {fibIndex}, callback,                            asyncState)    End Function         Public Function EndGetSeqNumber(ByVal asyncResult As System.IAsyncResult) As          Integer       Dim results() As Object = Me.EndInvoke(asyncResult)       Return CType(results(0),Integer)    End Function End Class 

The C# file contains:

 using System.Diagnostics; using System.Xml.Serialization; using System; using System.Web.Services.Protocols; using System.ComponentModel; using System.Web.Services;      [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="FibonacciSoap", Namespace="http://tempuri.org/")] public class Fibonacci : System.Web.Services.Protocols.SoapHttpClientProtocol {         public Fibonacci() {       this.Url = "http://localhost/WebServices/Fibonacci_vb.asmx";    }      [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Get SeqNumber", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]    public int GetSeqNumber(int fibIndex) {       object[] results = this.Invoke("GetSeqNumber", new object[] {                   fibIndex});       return ((int)(results[0]));    }         public System.IAsyncResult BeginGetSeqNumber(int fibIndex,                                             System.AsyncCallback callback,                                             object asyncState) {       return this.BeginInvoke("GetSeqNumber", new object[] {                      fibIndex}, callback, asyncState);    }         public int EndGetSeqNumber(System.IAsyncResult asyncResult) {       object[] results = this.EndInvoke(asyncResult);       return ((int)(results[0]));    } } 

Compiling the Source File

Now that you have the proxy source files, you need to compile them. Included with .NET are comm and-line compilers for C# ( csc.exe ) and VB.NET ( vbc.exe ). We'll use these to build the proxy classes into assemblies.

Compiling the VB.NET Source

To compile the VB.NET source file, execute the following statement at a command prompt (note that this command is all one line):

  vbc /t:library /out:Fibonacci_vb.dll   /reference:System.Web.Services.dll,System.Xml.dll,System.dll Fibonacci.vb  

This instructs the VB.NET compiler to create a library ( .dll ), rather than an executable, and to create a file named Fibonacci_vb.dll . Finally the VB.NET compiler is instructed to use Fibonacci.vb as the input source file. The result is a Fibonacci_vb.dll file.

Compiling the C# Source

To compile the C# source file, execute the following command (note that this command is all one line):

  csc /t:library /out:Fibonacci_cs.dll Fibonacci.cs  

The syntax for the VB.NET and C# compilers is identical, and after executing this statement the result is a .dll file named fibonacci_cs.dll .

You can copy either of these .dll files (you need only one of them) to an ASP.NET application's \bin directory. You can then build an ASP.NET application that uses this proxy, just as with Visual Studio .NET. For example:

 <Script runat="server"> Private Sub Page_Load(sender As Object, e As EventArgs)  Dim fibonacci As New Fibonacci ()     lblResult.Text = fibonacci.GetSeqNumber(6)  End Sub  The value of the 6th element in the Fibonacci series is:   <asp:label id="lblResult" runat="server"/>  

In the Visual Studio .NET version of this example, we used a Fibonacci proxy that was part of the localhost namespace. Our example of the proxy using the command-line tool didn't use a namespace. This is a choice we made. You could make the previous class part of a namespace with another simple command-line switch: namespace . For example:

  wsdl /namespace:localhost http://localhost/../Fibonacci_cs.asmx?WSDL  

The namespace and language parameters are just two of the parameters that wsdl.exe supports. Let's look at the others.

Using wsdl.exe

There are several parameters that can be used to configure the behavior of the wsdl.exe tool. A description of these parameters can be found by typing the following at a command prompt:

  wsdl.exe /?  

This returns a full listing of the switches the tool supports:

Parameters

Description

<url or path >

The URL or file path to one of these supported document types that WSDL.exe recognizes (WSDL Contract, XSD Schema, or DISCO Document).

/nologo

Hides the banner output when the tool is run.

/language: <language>

The language option (short form /l: ) allows you to create the proxy in any .NET language. Three languages are available as part of the SDK that the tool supports: C# ( /language:CS ), VB.NET ( language:VB) , and JScript.NET ( /language:JS ). The default language is C#. To use a language other than these three, you must name the class implementing the ICodeGenerator interface. For example, to use Perl, you would use a CodeDOM class provided by the .NET Perl compiler.

/server

By default, wsdl.exe will create client proxies for a given WSDL document. However, if you use the /server option, wsdl.exe will generate a source file with abstract members that represents the server implementation of the web service. This option is useful if several organizations agree upon the structure of the web service (as defined by the WSDL), but would like to provide their own implementations.

/namespace: <namespace>

The /namespace (short form /n: ) option allows you to set the namespace that the proxy class is generated within. By default, no namespace is used. For example, you can generate a proxy class within a namespace of MathSamples by simply setting /n:MathSamples .

/out:<filename>

The /out parameter allows you to name the source file created by wsdl.exe . By default, the name of this source file is [service name].[language extension] .

/protocol: <protocol>

ASP.NET Web services support three protocols: HTTPGet , HTTPPost , and SOAP . By default, SOAP is used for client proxies and is what WSDL will instruct the proxy class to use (through attributes in the source). You can override this setting by specifying one of these protocols: HttpGet , HttpPost , or SOAP .

/username: <username>

The /username parameter (short form /u: ) is set when you use a URL to access the WSDL, DISCO, or XSD Schema, and the server requires authentication.

/password: <password>

The /password parameter (short form /p: ) is set when you use a URL to access the WSDL, DISCO, or XSD Schema and the server requires authentication for a user.

/domain: <domain>

The /domain parameter (short form /d: ) is set when you use a URL to access the WSDL, DISCO, or XSD Schema, and the server requires authentication.

/proxy:<url>

The proxy server used for HTTP requests. By default the proxy settings defined for Internet Explorer are used.

/proxyusername: <username>

The name of the user to authenticate to the proxy server with.

/proxypassword: <password>

The value of the proxy user's password to authenticate to the proxy server with.

/proxydomain: <domain>

The name of the proxy user's domain to authenticate to the proxy server with.

/appsettingsurlkey: <key>

Rather than hardcoding the URL specified in the WSDL document, a URL can be stored in ASP.NET configuration system's < appSettings > section. You can use the appsettingsurlkey parameter with wsdl.exe to name the key that corresponds to the value stored in the configuration file.

/appsettingsbaseurl: <baseurl>

When used in conjunction with the appsettingsurlkey , this parameter allows you to name the base URL for the web service.

Now that you know how to use both Visual Studio .NET and wsdl.exe to create a proxy class, we can discuss the proxy that's generated. It inherits some properties and methods from a base class, and as you'll see, these properties and methods give even more control over how we interact with the web service that the proxy represents.




Professional ASP. NET 1.1
Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)
ISBN: 0470384611
EAN: 2147483647
Year: 2006
Pages: 243

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