The ASP.NET framework simplifies development of web services. All the low-level work, such as packaging and unpackaging data in XML format and utilizing HTTP protocol to transport the web messages between distributed components, are done by the framework. This allows the developers to focus on the application logic.
 We've seen web services in detail in Chapter 6. This section reviews web services briefly to remind you that the underlying support for web services is ASP.NET.
The .NET Framework uses asmx as the default file extension for web services, as opposed to aspx for Web Forms and ascx for web controls.
All asmx files start with the @WebService directive that instructs ASP.NET on how to compile the code, as well as the main class name. The WebService directive has the following attributes:
Specifies the language in which the code was written. This instructs the ASP.NET framework to use the appropriate compiler to build your web service. Use VB for Visual Basic, C# for C#, and JS for JScript .NET. As other languages emerge, obviously you can specify other languages.
Specifies the main class, which exposes web methods. The ASP.NET framework instantiates this class in order to serve the web methods to the clients.
Specifies the source file for your code, which allows for complete code/ASP separation.
You can easily create a simple Web Service similar to the following asmx file:
<%@ WebService Language="VB" class="MathClass" %> imports System.Web.Services Public Class MathClass <WebMethod> _ public function Add(a as integer, b as integer) as integer return(a + b) end function end class
Note the line continuation symbol right after <WebMethod>. If you prefer to separate your code completely from any ASP.NET elements, you could have the code for your Web Service saved in a separate file and specify the Codebehind attribute of the @WebService directive to point to the code file:
<%@ WebService Language="VB" Codebehind="MathClass.vb" Class="MathClass" %>
The source for MathClass.vb looks exactly like the asmx shown earlier minus the first line. You can use the following command line to compile MathClass.dll:
vbc /t:library /r:System.Web.Services.dll MathClass.vb
As with all code-behind, the binary has to be deployed in the /bin directory under the application.
Public methods of any classes can be tagged with the WebMethod attribute to be made accessible from the Web. The syntax for tagging attributes to methods is different for each .NET language. For example, in C# the tag takes the following form:
[WebMethod(attribute="value" attribute="value" . . . )] public returnType FunctionName(paramsList)
In VB, angle brackets are used instead of square brackets and the assignment symbol is ":=" instead of just "=". Also note that the whole web method declaration is on a single line. If you want to separate them for readability, use the line continuation symbol "_":
<WebMethod(attribute:="value" attribute="value" . . . )> Public Function FunctionName(paramsList) as returnType <WebMethod(attribute:="value" attribute="value" . . . )> Public Sub SubName(paramsList)
If you are using Visual Studio .NET, you can choose Project/Add Web Reference and then type in the URL where the Web Service resides. For our purpose, we'll point to the Web Service we created in the last chapter, PubsWS. The URL to this Web Service on our server is http://localhost/PubsWS/PubsWS.asmx. The default web reference name is the server name where the Web Service was found. After adding the web reference, you can access the proxy object to the Web Service you are calling via the type servername.proxyObjectName. For your case, it is localhost.PubsWS.
 In VS.NET 1.1, you can also browse the web services on your local machine in addition to browsing web services on UDDI servers.
 You can rename the web reference when adding it to your project. This way the Web Service will be <yourwebservicename>.proxyObjectName instead of servername.proxyObjectName.
The following code excerpt demonstrates how to use the Web Service through the proxy. We create an instance of the proxy object and then ask it to relay the message to the real Web Service to get the list of authors. The result will be streamed back in XML format, which is reconstructed into a DataSet object. We then bind DataGrid1, which is just a DataGrid object that we have on the Web Form, to the default view of the first table of the DataSet. Finally, we ask for the actual binding to take place. The resulting page is the grid populated with rows from the Authors table of the Pubs sample database:
localhost.PubsWS ws = new localhost.PubsWS( ); DataSet ds = ws.GetAuthors( ); DataGrid1.DataSource = ds.Tables.DefaultView; DataGrid1.DataBind( );
Instead of using Visual Studio .NET to locate and automatically generate the proxy class, you can also use the information from the previous chapter to generate the source for the proxy class yourself. You can then include or compile the source into a DLL and add the DLL to the project as a reference. In any case, the end result is the same. Here is an example that links against the proxy we created in the previous chapter and fills a grid with data:
<%@ Page Language="C#" %> <%@ Import Namespace="System.Data" %> <!-- Link to the proxy generated by wsdl.exe --> <%@ Assembly Src="PubsWS.cs" %> <html> <head> <title>SOAP Client</title> </head> <body> <!-- Make the SOAP call and fill the data grid. --> <% PubsWS ws = new PubsWS( ); DataSet ds = ws.GetAuthors( ); dg.DataSource = ds.Tables.DefaultView; dg.DataBind( ); %> <!-- Create a data grid. --> <asp:DataGrid id="dg" runat="server"/> </body> </html>