Before 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, you enter wsdl
at the Windows
command-line prompt, followed by the path to the WSDL contract. For
example, you might enter:
wsdl http://localhost/webforms/wscalc/service1.asmx?wsdl
The result is the creation of a C# client file named
Service1.cs, an excerpt of which appears in
Example 16-3. 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 16-3. Sample client code to access the calculator web service
using 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/webforms/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 (see Chapter 18), 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
which 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, you 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, you 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 you just created and a reference to
System.Web.Services.dll
. 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 = 1;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 16-4.
Example 16-4. A client program to test the calculator web service
using 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( );
// cal 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/ProgCSharpWebSvc/ WebService1.asmx/Add?x=23&y=22
In fact, if you put that URL into your browser, the browser will respond with the answer:
<?xml version="1.0"?> <double xmlns="http://tempuri.org/">45</double>
The key advantage SOAP has over HTTP-Get and HTTP-Post is that SOAP
can support a rich set of data types, including all of the C#
intrinsic types (int
, double
,
etc.), as well as enums, classes, structs, and ADO.NET DataSets, 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.
18.225.234.24