Web-Service Consumer Implementation

The thing about creating web services is that it's not a very satisfying experience. There's nothing to seeno visual reinforcement that we've accomplished anything. Fortunately, ASP.NET includes functionality to generate a test page for web services automatically.

We can simply use the browser to navigate to the ASMX file. Enter http://server/PTService/ProjectTracker.asmx into the address box, for example, and you'll get an informational display about the web service and its capabilities, similar to what's shown in Figure 10-13.

image from book
Figure 10-13: Example output from the ProjectTracker test web page

If we then click one of the links for a web method, we'll get details about that method. For instance, clicking the GetResourceList() method brings up a display similar to the one in Figure 10-14.

image from book
Figure 10-14: WSDL for the GetResourceList method

With simple web methods , this display includes the ability to invoke the method from within the browser. In our case, however, there are two roadblocks :

  • We're requiring a SOAP header, and that's not supported by the test pages generated by ASP.NET. These pages can never be used to invoke a web method that requires a SOAP header.

  • Our parameters and return types aren't simple data typesthey're complex structures. Because of this, the test pages can't be used to invoke our web methods.

What this means is that in order to test our web service, or to get any visual feedback that our methods work, we need to create a test application. We'll use VS .NET to create this test application, so it will be very easy to do. However, there's nothing to prevent the creation of similar applications using other tools on other hardware platforms or operating systems.

Creating the Project

Open a new project in a new solution. Make it a Windows application, and call it PTClient . We'll keep this very simple, because all we're trying to do is illustrate that we can write code to call each of our methods and have them work as planned.

The first thing we need to do is add a web reference so that we can make use of our ProjectTracker service. Choose Project image from book Add Web Reference to bring up the Add Web Reference dialog box. Navigate to the web service, either by using the links in the dialog box display, or by entering the URL directly into the URL text box. The result should be similar to Figure 10-15.

image from book
Figure 10-15: Adding a web reference for ProjectTracker.asmx

When we click the Add Reference button, VS .NET will add a reference to the web service. What then goes on behind the scenes is fairly extensive . VS .NET uses the WSDL description for our web service to determine all the types it exposes including CSLACredentials , ProjectInfo , and our other data structures, including the ProjectTracker class that contains our web methods. VS .NET uses this information to create consumer-side proxy classes for all these types, so we can use them in our consumer code as though they were local classes.

Tip 

Note that all of these typesincluding the struct sbecome classes. A web-services consumer has no way of knowing what is or isn't an object on the server. For all the consumer knows , the web service is written entirely in classic ASP, and hasn't got a class or an object anywhere . In the end, it really doesn't matter.

Once the reference is added, use Solution Explorer to change its name to PTService . It defaults to the name of the web server that's hosting the service, but that's typically not very descriptive or meaningful. Web servers can host many web services, so it's better to provide a more memorable name.

Handling Security on the Consumer

Now that the web reference has been set up, we can move on to code our test consumer. Essentially, calling a web service from C# is easyalmost trivial, in fact. However, in our case we've added a bit of a wrinkle, because our web methods require a custom SOAP header: a CSLACredentials object.

As you would expect, .NET fully supports this concept. We've already seen the server-side support, and there's also consumer-side support that makes the use of SOAP headers relatively painless.

When we want to call a web service, we create an instance of the consumer-side proxy object that represents it. In the case of our sample application, the proxy is called PTService.ProjectTracker .

The following line of code creates an instance of the proxy, as follows :

 PTService.ProjectTracker svc = new PTService.ProjectTracker(); 

And we then use this proxy to call our web methods. For instance, we'd normally do something like this:

 PTService.ProjectInfo [] proj;  proj = svc.GetProjectList(); 

If we try this for our service, however, we'll get a security exception like that in Figure 10-16, because we haven't provided the SOAP header.

image from book
Figure 10-16: Security exception due to lack of valid credentials

To supply a SOAP header, we need to create an instance of the SoapHeader classin our case, CSLACredentials and then attach that object to the consumer-side proxy for our web service, as follows:

 // Create the security credentials       PTService.CSLACredentials cred = new PTService.CSLACredentials();       cred.Username = "rocky";       cred.Password = "lhotka";       // Provide the credentials to the service proxy       svc.CSLACredentialsValue = cred; 

Because the CSLACredentials class was exposed by our web service, VS .NET automatically created a consumer-side proxy class for it that we can use to create and populate a CSLACredentials object. The WSDL definition for our web service also indicated that we have web methods that require this as a SOAP header, so VS .NET automatically added a CSLACredentialsValue property to our consumer-side proxy. To pass a CSLACredentials object to the server as a SOAP header, all we need to do is set this CSLACredentialsValue property!

Despite all of Visual Studio .NET's assistance, this is quite a lot of code to write each time we want to call a web method. We can encapsulate it into a single method that creates the consumer-side proxy and configures it appropriately. To make this a bit more efficient, we'll also cache the consumer-side proxy object so that it's only created on the first call.

Open the code window for Form1 , and add the following code within the form:

  #region Security     private PTService.ProjectTracker _service;     private PTService.ProjectTracker WebService     {       get       {         if( _service == null)         {           // Create the web service proxy           _service = new PTService.ProjectTracker();           // Create the security credentials           PTService.CSLACredentials cred = new PTService.CSLACredentials();           cred.Username = "rocky";           cred.Password = "lhotka";           // Provide the credentials to the service proxy           _service.CSLACredentialsValue = cred;         }         // Return the service proxy for use         return _service;       }     }     #endregion  

First, we'll see if we already have a consumer-side proxy object, as follows:

 if( _service == null) 

If we don't already have one, then we create it, along with a CSLACredentials object, and link the two, as shown here:

 // Create the web-service proxy       _service = new PTService.ProjectTracker();       // Create the security credentials       PTService.CSLACredentials cred = new PTService.CSLACredentials();       cred.Username = "rocky";       cred.Password = "lhotka";       // Provide the credentials to the service proxy       _service.CSLACredentialsValue = cred; 

Then we simply return the proxy, as shown here:

 // Return the service proxy for use       return _service; 

Now our code can simply call the WebService property anytime that it needs a reference to the web serviceall the details of security and SOAP headers are nicely encapsulated.

Calling Web Services

Since we've already taken care of the SOAP header details, calling methods on our web service will be pretty straightforward.

To see how this works, add a button named btnGetProject to the form, and then double-click it to bring up the code window. Enter the following code:

  private void btnGetProject_Click(object sender, System.EventArgs e)    {      PTService.ProjectInfo [] proj = WebService.GetProjectList();      MessageBox.Show(proj.Length.ToString(), "Number of projects returned");    }  

This code retrieves a list of project data from the server, and then brings up a message box to display the number of projects retrieved. First, we declare an array of type ProjectInfo in which we'll store the results. Then we populate it by calling the GetProjectList() method, as shown here:

 PTService.ProjectInfo [] proj = WebService().GetProjectList(); 

Since the ProjectInfo data structure was exposed as public in our web service, its definition was included in the WSDL. When we added the web reference, VS .NET automatically created a proxy class that mirrors the server-side structure, so we can just use that prebuilt proxy here.

We use the WebService property we created earlier, so all the SOAP header and security credentials are handled transparently . The result is an array of ProjectInfo objects, populated with the data returned from the server.

In the code download for this book, the PTClient application includes examples of calling all the other web methods in our ProjectTracker web service. Obviously, this is done just for testinga real consumer would presumably be doing other business operations, and would need access to our project or resource data within that context.



Expert C# Business Objects
Expert C# 2008 Business Objects
ISBN: 1430210192
EAN: 2147483647
Year: 2006
Pages: 111

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