[ Team LiB ] |
15.9 Creating the ProxyBefore you can create a client application to interact with the calculator web service, you must first create a proxy class. Once again, you can do this by hand, but that would be hard work. The folks at Microsoft have provided a tool called wsdl that generates the source code for the proxy based on the information in the WSDL file. To create the proxy, enter wsdl at the Windows command-line prompt, followed by the path to the WSDL contract. For example, you might enter: wsdl http://localhost/WSCalc/service1.asmx?wsdl The result is the creation of a C# client file named Service1.cs, an excerpt of which appears in Example 15-6. You must add the namespace WSCalc, because you'll need it when you build your client (the tool does not insert it for you). Example 15-6. Sample client code to access the calculator web serviceusing System.Xml.Serialization; using System; using System.Web.Services.Protocols; using System.Web.Services; namespace WSCalc { [System.Web.Services.WebServiceBindingAttribute( Name="Service1Soap", Namespace="http://www.libertyAssociates.com/webServices/")] public class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol { public Service1( ) { this.Url = "http://localhost/WSCalc/service1.asmx"; } [System.Web.Services.Protocols.SoapDocumentMethodAttribute( "http://www.libertyAssociates.com/webServices/Add", RequestNamespace= "http://www.libertyAssociates.com/webServices/", ResponseNamespace= "http://www.libertyAssociates.com/webServices/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle= System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public System.Double Add(System.Double x, System.Double y) { object[] results = this.Invoke("Add", new object[] {x,y}); return ((System.Double)(results[0])); } public System.IAsyncResult BeginAdd(System.Double x, System.Double y, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Add", new object[] {x, y}, callback, asyncState); } public System.Double EndAdd(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((System.Double)(results[0])); } This complex code is produced by the WSDL tool to build the proxy DLL you will need when you build your client. The file uses attributes extensively, but with your working knowledge of C# you can extrapolate at least how some of it works. The file starts by declaring the Service1 class that derives from the class SoapHttpClientProtocol, which occurs in the namespace called System.Web.Services.Protocols: public class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol The constructor sets the URL property inherited from SoapHttpClientProtocol to the URL of the .asmx page you created earlier. The Add( ) method is declared with a host of attributes that provide the SOAP goo to make the remote invocation work. The WSDL application has also provided asynchronous support for your methods. For example, for the Add( ) method, it also created BeginAdd( ) and EndAdd( ). This allows you to interact with a web service without performance penalties. To build the proxy, place the code generated by WSDL into a C# Library project in Visual Studio .NET and then build the project to generate a DLL. Be sure to write down the location of that DLL, as you will need it when you build the client application. To test the web service, create a very simple C# Console application. The only trick is that in your client code, you need to add a reference to the proxy DLL just created. Once that is done, you can instantiate the web service, just like any locally available object: WSCalc.Service1 theWebSvc = new WSCalc.Service1( ); You can then invoke the Pow( ) method as if it were a method on a locally available object: for (int i = 2;i<10; i++) for (int j = 1;j <10;j++) { Console.WriteLine( "{0} to the power of {1} = {2}", i, j, theWebSvc.Pow(i, j)); } This simple loop creates a table of the powers of the numbers 2 through 9, displaying for each the powers 1 through 9. The complete source code and an excerpt of the output is shown in Example 15-7. Example 15-7. A client program to test the calculator web serviceusing System; // driver program to test the web service public class Tester { public static void Main( ) { Tester t = new Tester( ); t.Run( ); } public void Run( ) { int var1 = 5; int var2 = 7; // instantiate the web service proxy WSCalc.Service1 theWebSvc = new WSCalc.Service1( ); // call the add method Console.WriteLine("{0} + {1} = {2}", var1, var2, theWebSvc.Add(var1, var2)); // build a table by repeatedly calling the pow method for (int i = 2;i<10; i++) for (int j = 1;j <10;j++) { Console.WriteLine("{0} to the power of {1} = {2}", i, j, theWebSvc.Pow(i, j)); } } } Output (excerpt): 5 + 7 = 12 2 to the power of 1 = 2 2 to the power of 2 = 4 2 to the power of 3 = 8 2 to the power of 4 = 16 2 to the power of 5 = 32 2 to the power of 6 = 64 2 to the power of 7 = 128 2 to the power of 8 = 256 2 to the power of 9 = 512 3 to the power of 1 = 3 3 to the power of 2 = 9 3 to the power of 3 = 27 3 to the power of 4 = 81 3 to the power of 5 = 243 3 to the power of 6 = 729 3 to the power of 7 = 2187 3 to the power of 8 = 6561 3 to the power of 9 = 19683 Your calculator service is now more available than you might have imagined (depending on your security settings) through the web protocols of HTTP-Get, HTTP-Post, or SOAP. Your client uses the SOAP protocol, but you could certainly create a client that would use HTTP-Get: http://localhost/WSCalc/Service1.asmx/Add?x=23&y=22 In fact, if you put that URL into your browser, the browser will respond with the following answer: <?xml version="1.0" encoding="utf-8"?> <double xmlns="http://www.libertyAssociates.com/webServices/">45</double> The key advantage SOAP has over HTTP-Get and HTTP-Post is that SOAP can support a rich set of datatypes, including all of the C# intrinsic types (int, double, etc.), as well as enums, classes, structs, and ADO.NET data sets, and arrays of any of these types. Also, while HTTP-Get and HTTP-Post protocols are restricted to name/value pairs of primitive types and enums, SOAP's rich XML grammar offers a more robust alternative for data exchange. |
[ Team LiB ] |