Consuming the XML Web Service

.NET enables you to create an XML Web service proxy class in two ways. If you are using Visual Studio .NET, you can generate the proxy class using the Web reference feature (as shown in Figure 5-5). Just start a normal ASP.NET, Console, or Windows client project. Then right-click on the project in Solution Explorer and choose Add Web Reference. You can then enter the WSDL document location, or you can enter a Web URL that identifies a page or discovery document that links to the XML Web service and then browse to it using the appropriate link.

Figure 5-5. Adding a Visual Studio .NET Web reference

graphics/f05dp05.jpg

Figure 5-5 shows the version of the Add Web Reference dialog box that you'll see in Visual Studio .NET 2003. In earlier versions, the window is functionally equivalent but looks a little different. Visual Studio .NET 2003 also adds a few links that allow you to easily search for UDDI Web servers and browse the information they provide.

When you click Add Reference, the proxy class is generated in the language of the current project and is added to the project. By default, however, the proxy class is hidden because it shouldn't be modified directly. If you want to examine the proxy class, choose Project, Show All Files from the Visual Studio .NET menu. By default, the proxy class file has the name Reference.vb and is grouped under the server name in the Web References section of Solution Explorer (as shown in Figure 5-6).

Figure 5-6. The Reference.vb proxy class file

graphics/f05dp06.jpg

Even if you aren't using Visual Studio .NET, you can still create the proxy class using the WSDL.exe command-line utility that is included with the .NET Framework. This utility is found in the .NET Framework directory, such as C:\Program Files\Microsoft.NET\FrameworkSDK\Bin.

The syntax for WSDL.exe is shown here. Table 5-3 describes each field.

 wsdl /language:language  /protocol:protocol /namespace:myNameSpace      /out:filename /username:username /password:password      /domain:domain <url or path> 

A typical WSDL.exe command looks something like this (split over two lines):

 wsdl /language:VB /namespace:localhost       http://localhost/CustomerDB/CustomerDB.asmx?WSDL 

This creates a CustomerDB.vb proxy class file. You can then add this file to a client project or compile to a DLL using the vbc.exe command-line compiler, as shown here:

 vbc /t:library CustomerDB.vb 

Table 5-3. WSDL.exe Command-Line Parameters 

Parameter

Description

Language

This is the language that the proxy class will use. The language really doesn't matter because you won't directly modify the proxy class code (because any changes are lost every time you regenerate it). The default is C#.

Protocol

Usually, you will omit this option and use the default (SOAP). However, you can also specify HTTP GET and HTTP POST for more limiting protocols.

Namespace

This is the .NET namespace that your proxy class will use. If you omit this parameter, no namespace is used and the classes in this file are available globally. For better organization, you should choose a logical namespace. Visual Studio .NET automatically uses the server name (for example, localhost).

Out

This enables you to specify the name for the generated file. By default, this is the name of the service followed by an extension indicating the language (for example, CustomerDB.vb).

Username, password, and domain

You should specify these values if the Web server requires authentication to access the virtual directory.

URL or path

This piece of information is always added at the end of the WSDL.exe command line. It specifies the location of the WSDL document for the Web service.

Examining the Proxy Class

It's not necessary to examine the proxy class, but doing so provides some interesting insights into how the .NET XML Web service framework works. Essentially, the proxy class mimics the XML Web service, reproducing every Web service method. The client then creates an instance of the proxy class and calls one of its methods. Behind the scenes, the proxy class packages the information into a SOAP request message, waits for the SOAP response message, and then converts the return value into a standard .NET data type, which it then passes back to the client.

Listing 5-2 shows a shortened version of the autogenerated CustomerDB proxy class. Notice that it includes a copy of the CustomerDetails class, which allows the client to use this type natively. The proxy class also includes specialized Begin and End versions of each Web method (as in BeginGetCustomer and EndGetCustomer), which allow the Web method to be called asynchronously. These methods, which aren't shown here, are examined in more detail in the next chapter.

Listing 5-2 The proxy class for the CustomerDB service
 Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Xml.Serialization Namespace localhost          <WebServiceBinding(Name:="CustomerDBSoap",      [Namespace]:="http://www.prosetech.com/"), _      XmlIncludeAttribute(GetType(System.Object()))> _     Public Class CustomerDB         Inherits SoapHttpClientProtocol                  Public Sub New()             MyBase.New             Me.Url = _              "http://localhost/WebServices/CustomerDB/CustomerDB.asmx"         End Sub         <SoapDocumentMethod("AddCustomer"> _         Public Sub AddCustomer(ByVal customer As CustomerDetails)             Me.Invoke("AddCustomer", New Object() {customer})         End Sub                          <SoapDocumentMethod("UpdateCustomer"> _         Public Sub UpdateCustomer(ByVal customer As CustomerDetails) 
             Me.Invoke("UpdateCustomer", New Object() {customer})         End Sub                  <SoapDocumentMethod("DeleteCustomer"> _         Public Sub DeleteCustomer(ByVal customerID As Integer)             Me.Invoke("DeleteCustomer", New Object() {customerID})         End Sub                  <SoapDocumentMethod("GetCustomer"> _         Public Function GetCustomer(ByVal customerID As Integer) _          As CustomerDetails             Dim results() As Object = Me.Invoke("GetCustomer", _               New Object() {customerID})             Return CType(results(0),CustomerDetails)         End Function                  <SoapDocumentMethod("http://www.prosetech.com/GetCustomers"> _         Public Function GetCustomers() As CustomerDetails()             Dim results() As Object = Me.Invoke("GetCustomers", _               New Object(-1) {})             Return CType(results(0),CustomerDetails())         End Function         <SoapDocumentMethod("http://www.prosetech.com/GetCustomersDS"> _         Public Function GetCustomersDS() As System.Data.DataSet             Dim results() As Object = Me.Invoke("GetCustomersDS", _               New Object(-1) {})             Return CType(results(0),System.Data.DataSet)         End Function     End Class              <System.Xml.Serialization.XmlTypeAttribute()>  _     Public Class CustomerDetails         Public ID As Integer         Public Name As String         Public Email As String         Public Password As String     End Class End Namespace 

The proxy class gains the ability to send SOAP messages over the Internet because it inherits from the SoapHttpClientProtocol class, which provides an Invoke method. Notice that each method receives a result as a generic object, which it then converts to the expected strongly typed class or structure.

By contrast, .NET Remoting uses its own dynamic proxy mechanism. .NET Remoting proxies are created at run time, whereas XML Web service proxies are created at design time. As a side effect, if the XML Web service changes, you must first recompile the XML Web service and then regenerate the proxy class. In Visual Studio .NET, you can accomplish this quickly by right-clicking on the Web reference in Solution Explorer and choosing Update Web Reference.

Using the Proxy Class

Using the proxy class is easy in fact, it works just like any other object. Listing 5-3 and Figure 5-7 show a sample Windows client that gets the list of all customers and displays in a DataGrid control. This example is nearly identical to the local data component example in Chapter 3, even though the method call is invoked over the Internet. If you use Visual Studio .NET, you can even enter Break mode and single-step from the client code into the XML Web service code.

Listing 5-3 A basic Windows client
 Public Class WindowsClient     Inherits System.Windows.Forms.Form     ' (Designer code omitted.)     Private Sub WindowsClient_Load(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles MyBase.Load         Dim DBProxy As New localhost.CustomerDB()         DataGrid1.DataSource = DBProxy.GetCustomerDS().Tables(0)     End Sub End Class 
Figure 5-7. Retrieving query results through an XML Web service

graphics/f05dp07.jpg

And here's an example that shows how you can interact with the CustomerDetails object defined by the XML Web service:

 Public Class WindowsClient     Inherits System.Windows.Forms.Form     ' (Designer code omitted.)     Private Sub WindowsClient_Load(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles MyBase.Load         Dim DBProxy As New localhost.CustomerDB()         Dim Customer As localhost.CustomerDetails         Customer = DBProxy.GetCustomer(1)         MessageBox.Show("CustomerID 1 is: " & Customer.Name)     End Sub End Class 

Keep in mind that this is really just a remote procedure call. The XML Web service doesn't retain any state. Therefore, even though you retain a reference to the proxy class, the actual XML Web service instance is created at the beginning of every method invocation and is destroyed at the end. This means that you can't set instance variables or properties and expect the values to persist between method calls.

By default, the proxy sends its SOAP message over the default HTTP port used for Web traffic: 80. You can also tweak some proxy class settings to adjust this communication if needed. If you need to connect through a computer called MyProxyServer using port 80, for example, you can use the following code before you call any proxy methods:

 Dim ConnectionProxy As New WebProxy("MyProxyServer", 80) Dim DBProxy As New localhost.CustomerDB() DBProxy.Proxy = WebProxy 

Similarly, you can adjust the amount of time the proxy waits for a SOAP response before timing out and throwing an exception, as follows:

 DBProxy.Timeout = 10000  ' 10000 milliseconds is 10 seconds. 

Debugging Web Services

It's possible to debug an XML Web service in a separate instance of Visual Studio .NET or as part of a multiproject solution. However, you'll need to tweak the debugging settings so that your XML Web service code is compiled and loaded into the debugger. Otherwise, you won't be able to set breakpoints, use variable watches, or rely on any of the other indispensable Visual Studio .NET debugging features.

To enable XML Web service debugging, right-click on the project in Solution Explorer and choose properties. Then under the Configuration Properties | Debugging node, choose Wait For External Process To Connect, as shown in Figure 5-8. This instructs Visual Studio .NET to load the debugging symbols when you run the XML Web service, instead of simply showing the XML Web service test page.

Figure 5-8. Configuring an XML Web service for debugging

graphics/f05dp08.jpg

If you're testing a compiled client or a client in another instance of Visual Studio .NET, just be sure to start the XML Web service project first in order to debug it. If you're creating a solution that includes both a client and an XML Web service, you can configure it to have multiple startup projects, exactly as you would with .NET Remoting. Simply right-click on the solution item in the Solution Explorer, and choose Properties. Figure 5-9 shows an example in which both an XML Web service and a client application are launched when the solution is started.

While testing an XML Web service, you might encounter the infamous "unable to start debugging on the server" error. This signals that Visual Studio .NET was able to compile the XML Web service but can't execute it in debug mode. Unfortunately, this problem can result because of countless different reasons. One common problem occurs if you install IIS after you install the .NET Framework. In this case, you can "repair" the .NET Framework using the original setup CD or DVD. Microsoft describes this process and a number of other possible causes for this error in a white paper at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebug/html/vxtbshttpservererrors.asp. One common cause not mentioned is failing to create the virtual directory or trying to run a program after you've removed or modified the virtual directory. To correct these problems, modify the virtual directory settings in IIS Manager.

Figure 5-9. Starting an XML Web service and client

graphics/f05dp09.jpg

Another problem that can occur in Visual Studio .NET 2003 is a failure to authenticate. Visual Studio .NET 2003 attempts to access the local Web server using integrated Windows authentication, even if you have anonymous authentication enabled for the virtual directory. Thus, your virtual directory must allow both anonymous and Windows Integrated authentication. To allow for this, follow these steps:

  1. Start IIS Manager.

  2. Right-click the virtual directory for your application, and choose Properties. (Alternatively, you can configure authentication for all directories if you right-click the Web Sites folder and choose Properties.)

  3. Select the Directory Security tab.

  4. In the Anonymous access and authentication section, click the Edit button.

  5. In the Authentication Methods dialog box, under Authenticated access, select Integrated Windows Authentication, as shown in Figure 5-10.

    Figure 5-10. Enabling Windows authentication for debugging

    graphics/f05dp10.jpg

  6. Click OK to apply your changes.



Microsoft. NET Distributed Applications(c) Integrating XML Web Services and. NET Remoting
MicrosoftВ® .NET Distributed Applications: Integrating XML Web Services and .NET Remoting (Pro-Developer)
ISBN: 0735619336
EAN: 2147483647
Year: 2005
Pages: 174

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