Day 16: Creating Web Services

Yesterday you learned about building components for your ASP.NET applications. These components can be used over the Internet to provide functionality for your ASP.NET pages. What happens, though, when you want these components to be available without having to use ASP.NET pages?

Web services are a new way to deploy applications. Using XML and other standard technologies, Web services enable applications and components to talk to other applications no matter where they're located, whether it's on the same machine or across the globe.

Today will be spent learning all about building Web services. They're a revolutionary way to think about Web applications and are an essential topic for ASP.NET developers. Tomorrow, you'll learn how use these services in your ASP.NET applications.

Today's lesson will cover the following:

The Way the Web Works—Revisited

When you began your journey through ASP.NET 15 days ago, you examined the fundamental operations of the Web—namely, the request/response model of operation. A client (such as a browser) requests a page from a Web server, and the server sends the page back to the client through a response.

Then you learned about the programmable Web. ASP.NET and other technologies allow you to perform tasks when the pages are requested. You can serve data to clients dynamically by providing programmatic capabilities on the server. Although ASP.NET extends this model by placing an event-driven mechanism on top, the fundamental mechanism of the Web is still the same: request/response.

ASP.NET pages provide a front end that allows users to interact with a Web site. Behind the UI, possibly in business objects, there may be some powerful application logic. What if the functionality in one Web site is so useful that other programmers want to include it in their sites? Or what if people want to use the functionality but can't use the UI, such as if they're working from a command prompt? How do you take advantage of the request/response model in these situations?

It's easy. Think of the way ASP.NET pages interact with business objects. They use methods and properties provided by the objects to perform some functionality, and the object may or may not return some information. In essence, you're sending a request to perform some function and waiting for a response.

Why can't any other application interact with the objects the same way? Just send a command over the Internet and wait for a response. Figure 16.1 illustrates this concept. The idea is very simple, but until now the technology to make it happen didn't exist.

In a more real-world example, one Web site should be able to make a request of a second Web site and wait for a response. The first Web site could interact with methods and properties available at that second. Figure 16.2 illustrates this concept with a stock price service. The user makes a request from a Web site, which in turn makes a request from a stock exchange site. The second Web site returns the data to the first, which can display the data to the user in any way it wants.

Figure 16.1
Applications should be able to interact with Web services just as ASP.NET pages interact with business objects.

Figure 16.2
Web services allow Web sites to use functionality available on other sites.

Introduction to Web Services

New Term - Before you learn about Web services, it's a good idea to examine what a regular service is. When someone does a task for you, he's providing you a service. For example, you can go to a gas station and fill up your gas tank, or receive a tune-up. These are services provided to you by the gas station so that you don't have to do it yourself. Imagine if everyone had to have their own gas pump. Not an ideal situation. You also go to restaurants to receive food service. This is the type of task you can do yourself, but it requires work that you may not be willing to do. So a service is a value-added task provided by a person (or company) that frees you from having to do it yourself.

A Web service is the same thing. Web sites can provide a service that visitors, or even other Web sites, can take advantage of. Imagine a Web portal that presents information such as local and national news, weather information, sports scores, and other personalized content. It provides a service to visitors by compiling information from many different sources into one place. However, unless the portal has a very large budget and a huge staff, it's nearly impossible to keep writing up-to-date content for all these different sections. Instead, the portal can rely on content from other sites and simply provide the display mechanism. The portal still provides a service to users, but it relies on services provided by other sites.

This is already widespread in news reporting. The Associated Press provides a news service that newspapers can tap into. Next time you're reading a newspaper, look for articles written by the Associated Press. They've been pulled from a news service.

This type of system hasn't been widely used on the Internet because of complications involving how services should communicate. Many companies have attempted to build proprietary communication systems that allow services to be exchanged, but these are often too complex and expensive to be adopted by the general community. Also, problems have arisen due to the structure of security systems on the Internet. Many of these proprietary systems have difficulty transferring data across firewalls, which are designed to stop unauthorized traffic.

Web services, provided by the .NET Framework, are a solution to these and other problems. A Web service is a programmable object (just like a business object) that provides functionality that's accessible to any number of systems over the Internet. The reason Web services work is that they rely on standardized technologies for objects to communicate. Customized systems and proprietary mechanisms aren't necessary for Web services to work. All you need is an Internet connection.

Web services rely on the fact that any type of system or application can use HTTP, the standard protocol for Internet communication, and can use and convert XML, a standard for delivering data over the Web. Web services use XML to send commands and move data to and from objects residing on one server. The applications that use the data and send the commands can be written in any language, for any computer architecture, and they can be simple or complex. All the applications need to know is the Web service's location (basically, its Internet address).

Web services provide a new level of computing. In much the same way that you can assemble various objects and components to build an application, developers can assemble a group of Web services from completely different locations and use them in their own applications. Completely different platforms can now communicate easily, enabling disparate systems around the world to be tied together.

Web Service Scenarios

Imagine that you've built a component that performs simple calculation functions, like the calculator you built on Day 2, "Building ASP.NET Pages." Recall that the calculator performed simple arithmetic operations. Another Web site somewhere has built a component that can place orders to a home improvement store. Assuming these two components are Web services, a savvy developer could link them to create an application that allows a user to design her home. When the user needs to determine measurements and calculations, she uses your Web service's calculation functions. Then she places an order to the home improvement store through the other Web service. All this is accomplished from within one application, and the user doesn't need to know where the pieces of functionality came from. Figure 16.3 illustrates this example.

Figure 16.3
A single application can tie together many Web services.

Web services can even be used by Internet applications. Imagine an e-commerce site that must calculate shipping charges for customers ordering supplies. Normally, this site would have to maintain an up-to-date table for calculating shipping costs based on the shipper, the shipping location, the priority, and so on. With Web services, the site can place a "call" to the shipping company directly, using a brief XML command, and receive the quotes instantly. Web services easily tie together applications that were once very difficult to assemble.

The Web Service Programming Model

As mentioned earlier, Web services use XML to communicate. But what exactly is being communicated?

New Term - The first messages that are sent usually involve a process known as discovery, which is how a client application finds and examines a Web service. The discovery process involves messages sent to and from the service that describe what the service can do. The client needs to know this before it tries to use the service. The service also tells the client what other kinds of messages it will accept.

The discovery process is not a necessary one. For instance, if a service doesn't want anyone to know about it, it can disable the discovery process. This is a protective measure so that not just anyone can use a particular Web service you've created.

Following discovery, the service must tell the client what it expects to receive (that is, which commands it will accept) and what it will send back. This is a necessary step so that both service and client know how to communicate with each other. This data is known as a Web service description. In a business object, the developer typically knows ahead of time which commands the object will support (through the documentation provided, for instance). The service description is essentially the documentation for the service in XML format.

Finally, messages are sent back and forth with commands to the service and data for the client, again in XML. Figure 16.4 illustrates the entire process.

Figure 16.4
Interaction with a Web service involves discovery, description, and commands.

Luckily, ASP.NET provides most of the infrastructure needed to perform all of these operations. After all, it can handle requests and responses, translate XML, and use business objects, making it ideal for Web service development. You just need to decide what your Web service will do and then build it.

Protocols for Accessing Web Services

You know that Web services rely on XML-formatted messages to send data and receive commands. Specifically, they use XML in the discovery process and service description. The messages containing commands aren't required to use XML, however. They can be sent in two additional methods, Http-Get and Http-Post, which are used in ASP.NET pages in querystrings and forms, respectively.

Web services support three protocols for interacting with clients: Http-Post, Http-Get, and the Simple Object Access Protocol (SOAP). Discussing these protocols in any depth is beyond the scope of this book, but you should have a basic understanding of them and how they affect Web services.

Http-Get

Http-Get is a standard protocol that enables clients to communicate with servers via HTTP. Http-Get is the way that you typically request Web pages. Think of the Http-Get operation as a client getting a Web page from a Web server. In essence, a client sends an HTTP request to the URL of the Web site, which responds with the appropriate HTML. Any parameters that are needed to process the request are attached via the querystring. For example:

http://www.myserver.com/default.aspx?id=Chris&sex=male

The parameters id and sex are passed as inputs to the Web server, attached to the end of the URL. An ASP.NET page could then retrieve these values with this code:

Request.Querystring("id")
Request.Querystring("sex")

Web services can use Http-Get and the querystring to pass commands and parameters, instead of XML messages. Note that information sent with Http-Get is part of the URL. Http-Get has limited functionality, however, because it can only send name/value pairs.

Http-Post

This protocol is similar to Http-Get, but instead of appending parameters onto the URL, it places them directly in the HTTP request message. When a client requests a page via Http-Post, it sends an HTTP request message with additional information that contains parameters and values. The server must then read and parse the request to figure out the parameters and their values. The most common use of Http-Post is in HTML forms.

For example, imagine an HTML form with the fields id and sex, as shown in the following code snippet:

<form method="post">
  <input type="Text" id="id">
  <input type="Text" id="sex">
  <input type="Submit" id="btSubmit" Value="Submit" />
</form>

When you submit this form, your browser takes the values entered in the text boxes and adds them to HTTP request message to the server. The server can retrieve these values with this syntax:

Request.Form("id")
Request.Form("sex")

This protocol, like the Http-Get protocol, is limited to sending name/value pairs.


Note

Note that you can also send information via Http-Get with forms. In the form method, simply specify "Get" and the form will add the information to the querystring instead of the HTTP request header. For instance:

<form method="Get">

SOAP

The Simple Object Access Protocol (SOAP) is a relatively new standard that allows clients to send data to servers and vice versa. Unlike Http-Get and Http-Post, SOAP relies on XML to relay its information instead of an HTTP request message. This means that SOAP can send not only name/value pairs, but more complex objects as well, such as various rich data types, classes, objects, and others.

Sending SOAP messages is a bit different than what we're used to. With Http-Get we send information via the querystring, and with Http-Post, we send it via form submissions. Both methods rely on the request/response model of operation. SOAP information is also transported via HTTP, but isn't limited to the request/response model. It can be used to send any types of messages, whether a client has requested them or not. Thus, SOAP is a very flexible medium to send data.

Because SOAP is based on XML, you can use it to transport data around the Web. XML is simply pure text, so it can be sent anywhere HTML pages can, including through firewalls. This is the default protocol that Web services use to communicate with clients.


Note

Many people get confused when comparing SOAP and XML. If SOAP is such a great way to send messages, why not use it instead of XML? The difference is that XML defines a data format, while SOAP defines a protocol for exchanging that data. SOAP relies on XML to send its messages. Plain XML is ideal for transporting most types of data. It's only when you want to transfer things such as commands and instructions that SOAP applies.


Why Web Services?

Now that you know what Web services are, why should you use them?

Try to remember the world 10–15 years ago, before the rise of the Internet. Computer systems were usually standalone entities with no access to other systems. Applications were designed for use on one machine, with no sharing of data in any way. There was very little communication via computer within or between companies. Even interpersonal messages often had to be delivered by hand.

The Internet has changed the way the world communicates. It's also transformed the way applications are built. There are very few applications that don't take advantage of the Internet somehow. Many applications, such as instant messaging, rely on the Internet to provide users with data.

The next step in connecting users over the Internet is to deliver applications this way. Already, corporations are trying to tie traditional applications together into a single composite entity. When you consider the number of legacy applications still in use, this is a daunting task.

Web services provide a very simple mechanism for applications to communicate with each other. They allow components to be shared and functionality to be delivered to anyone, anywhere. Imagine never having to install another program on your computer again—simply connect to the Web and access the service.

All this may be great, but how do Web services make Web development better? One of the ways is through code reuse. Recall that one of the reasons for using business objects is that you can reuse the same code over and over again without having to create it each time. Even branching logic such as functions and subroutines promotes code reuse (see Day 3, "Using Visual Basic.NET."). With Web services, you can now reuse code that other people have developed without having to download, copy, or install anything. This saves you time and energy, enabling you to easily add functionality to your ASP.NET applications.

Another benefit of Web services is ease of deployment and maintenance. No longer will you have to install custom objects or applications on many different systems. Instead, users will have a standard framework for accessing your application—directly over the Internet. Also, when changes need to be made, you won't have to issue a new release or an update. Simply make the changes in your Web service in one place, and all clients will benefit from it automatically. (Unless, of course, the change removes functionality that clients depend on, in which case they have to adjust. Either way, the process is easier for the developer.)

Building a Web Service

There are several steps to building a Web service, including building the actual functionality and the service description. The following sections will take you through each step with a simple Web service.

Building the Functionality

Web service files are essentially VB.NET source files that end in an .asmx extension. A Web service, then, is represented by a class that derives from the WebService class. Listing 16.1 shows a very simple Web service.

Listing 16.1 A Simple Web Service

1  <%@ WebService Language="VB" Class="Calculator" %>
2
3  Imports System.Web.Services
4
5  public Class Calculator : Inherits WebService
6    <WebMethod()> Public Function Add(intA As Integer, _
7     intB As Integer) As Integer
8      Return(intA + intB)
9    End Function
10  End Class

Analysis

Save this file as c:\inetpub\wwwroot\tyaspnet21days\day16\ Calculator.asmx. On line 1 you see the @ WebService directive, which is similar to the @ Page directive and declares that this file represents a Web service. This directive supports the familiar Language attribute, which you set to VB. The directive also supports one other attribute, Class. This is the name of the Web service class that you're developing. In fact, on line 5 you see that the class name is indeed Calculator. A bit later, you'll learn about a neat feature of this attribute.


Next, you import the System.Web.Services namespace on line 3. This allows you to use all the necessary methods and classes of Web services. The class that you define on line 5 must inherit from the WebService class in this namespace.


Note

You can have many classes in one .asmx file, but only one may be used for the Web service—the one declared with the WebService directive at the top of the page.


Next, let's examine the only function in this class. The declaration for the Add method is pretty standard, with two notable items. The first is that the method must be declared public, meaning any other class or object can use it. If not, clients couldn't access this method of the Web service.

The second is the <WebMethod()> attribute, which tells ASP.NET that this method is available as a service to other applications. This is a very important attribute that must be present in order for clients to access methods, and you'll examine it a bit further later today in "The WebMethod Attribute."

Thus, methods that you want a client to access must be declared with Public and must contain the <WebMethod()> attribute.

Let's view this page in a browser. Figure 16.5 shows the output.

Figure 16.5
Viewing an .asmx file in a Web browser.

This is very interesting. What happened to the code? And where did the UI portion come from?

Like ASP.NET pages, .asmx files are compiled upon the first request. ASP.NET then serves up the service description whenever the page is requested. Figure 16.5, in XML form, is what a client would see when he tries to access your service. The response tells the client the class name, Calculator, and the methods and properties that are publicly available for use. Click on Service Description on the right side of the page. This directs you to the same page with a querystring appended:

http://localhost/tyaspnet21days/day16/Calculator.asmx?WSDL

The WSDL tells ASP.NET that you want to see the service description in XML form. Figure 16.6 shows the XML for this service.

That's quite a bit of XML for one small Web service. This XML file uses a standard format called the Service Description Language (SDL) to tell clients what can be done with this service. We won't delve into this XML in any depth, but you should notice some familiar items. For instance, there's the following near the top of the output:

1  <s:element name="Add">
2    <s:complexType>
3     <s:sequence>
4       <s:element name="intA" type="s:int"/>
5       <s:element name="intB" type="s:int"/>
6     </s:sequence>
7    </s:complexType>
8  </s:element>
9  <s:element name="AddResponse">
10    <s:complexType>
11     <s:sequence>
12       <s:element name="AddResult" type="s:int"/>
13     </s:sequence>
14    </s:complexType>
15  </s:element>

Analysis

The first element describes your method, Add, and the parameters it takes. The second element describes the response from your method, aptly named AddResponse. The rest of the file describes how the Http-Get, Http-Post, and SOAP protocols should access this service.


Figure 16.6
The XML service description for your Web service.

Let's go back to the regular view of the .asmx file. Click the Add method and find out what else ASP.NET has in store for you. Figure 16.7 shows this page.

Figure 16.7
A detailed description of the Add method.

It's clear that there are a lot of parts to Web services. This page, known as the HTML Description Page, details a lot of interesting items and even lets you test out the method. Enter two values in the text boxes and click the Invoke button. A new window opens up with the XML-formatted answer. This is exactly the response a client would receive after calling this Web method. The next three sections of the page, SOAP, HTTP GET, and HTTP POST, show examples of the different methods that these protocols must use to access this Add method.

This page allows you to test your services. Note that because you're using a form to submit the data, you're using the Http-Post protocol to communicate with the service.

Enabling Discovery

Discovery is the process by which a client application finds a Web service and determines what it can do. This information is supplied by the service description, but most clients won't know (and shouldn't know) the filename of this description. Therefore, enabling discovery means giving clients links to these descriptions.

Discovery is enabled through .disco files for the Web service. These files are XML documents that contain links to descriptions of the service. Clients can access this file to figure out more about the available Web services.

Creating .disco files is simple. Listing 16.2 contains a sample discovery file for your calculator service.

Listing 16.2 The Discovery File for Your Calculator Service

1  <?xml version="1.0"?>
2  <disco:discovery
3    xmlns:disco="http://schemas.xmlsoap.org/disco/"
4    xmlns:scl="http://schemas.xmlsoap.org/disco/scl">
5    <scl:contractRef ref="Calculator.asmx?WSDL"/>
6  </disco:discovery>

Analysis

Save this file as calculator.disco. As you can see, this file is very simple because it only contains a link to the description of your service, shown on line 5. The additional namespaces provided by the xmlns tags specify the URLs that define which valid names the scl and disco tags can use. In other words, the xmlns tags provide links to standard definitions of the scl and disco tags. Without these namespaces, your application won't know what to do with these extra tags.


The disco:discovery tag provides the links for a client to follow if he wants to find out about a Web service. These links can be to other .disco documents, or to service descriptions. Service description links are provided with the scl tags, as shown on line 5. To provide a link to another .disco file, use the following syntax:

<disco:discoveryRef ref="link" />

Request this file from your browser and you should see the same XML file.


Note

The discovery file isn't necessary for clients to access Web services. If they know the proper URL, they can simply access the service description itself. Discovery documents only help anonymous clients find Web services that you want to make publicly available.


The WebMethod Attribute

Web services have methods just as regular classes and business objects do. However, only the methods marked with the WebMethod attribute (as shown on line 6 of Listing 16.1) are viewable to clients of the Web service. Recall from yesterday that only public variables are accessible to ASP.NET pages using a business object, while private methods are only viewable by the object itself. In the same way, WebMethod restricts access to clients.

Web methods act like regular class methods. They can interact with the ASP.NET Session or Cache objects (see Days 4, "Using ASP.NET Objects with C# and VB.NET" and 14, "Using ASP.NET's Improved Caching Capabilities"), they provide buffered responses just as ASP.NET pages do (Day 4), and they can interact with databases and data sources. In essence, they are exactly the same as regular class methods, with one, large, exception: They can be accessed over the Internet.

This is a very important concept. After all, the methods of a class are one of the most important parts; they represent how a user will interact with the class. Methods with the WebMethod attribute treat all callers as if they were local. In other words, there is no difference if you call a Web method from an ASP.NET page in the same directory as the .asmx file, or from another server halfway across the world. This attribute is the key that allows Web services to be usable by clients; let's examine it further. The WebMethod attribute has a lot of interesting features. It's represented by the WebMethodAttribute class, which operates just like any other .NET class, with properties and methods. Thus, when you insert the attribute as follows, you're actually creating a new instance of the WebMethodAttribute class:

<WebMethod()> Public Function Add(intA As Integer)

Assigning values for the properties of this class is a bit different from what you're used to. For example:

<WebMethod(Description:="Adds two numbers ")> Public Function _
  Add(intA As Integer,intB As Integer)

You specify the property and value in the parentheses directly in the function declaration. Notice the colon before the equals sign—this means that you're initializing a property, and not supplying parameters. If you simply used:

<WebMethod(Description:="Adds two numbers ",_EnableSession:=False)>
  Public Function Add(intA As Integer,intB As Integer)

ASP.NET would think that Description="Adds two numbers" is the name of a variable that should be used to construct the WebMethod. This makes for an odd-looking function declaration, but it lets you set properties for this WebMethod. Multiple properties are separated by commas:

Public Function <WebMethod(Description:="Adds two numbers", _
  EnableSession:=False)> Add(intA As Integer, intB As Integer)

Table 16.1 describes the properties you can set.

Table 16.1 WebMethod Properties

Property

Description

BufferResponse

Specifies whether or not to buffer the output from the Web service. The default value is true, which specifies that any generated response is buffered on the server before being sent to the client. The data is sent back in chunks.

 

If you're returning large amounts of data, it may be beneficial to set this property to false. This causes the data to stream to the client, providing slightly better performance. Otherwise, this property should always be true.

CacheDuration

Web Methods are cacheable, just as ASP.NET pages are. This property gives the number of seconds the response should be cached. The default is 0, meaning caching is disabled.

 

When this property is set to anything other than 0, the response is cached for that number of seconds and all subsequent calls to this method from the client will retrieve the data from the cache, rather than executing the method again.

 

When you're sending large amounts of data, this property should be enabled. See Day 14 for more caching suggestions.

Description

This property provides a description of the Web method for clients. This description is viewable in the service description. The default value is String.Empty.

EnableSession

Specifies whether or not session state is enabled for the current method. If this is enabled (which it is by default), you can use the Session object to store data. If you don't need to store any data in session variables, you may want to turn this option off. You'll receive an increase in performance.

MessageName

This parameter is the name by which the Web method is called within the data that's sent to and from the service. By default, it's the same as the Web method's name.

 

This parameter is most often used to make method names unique. For instance, if you had two overloaded Add methods that each took different parameters, you could use MessageName to distinguish the methods. This property must be unique to the service description.

TransactionOption

Like databases, Web services can also participate in transactions. Within a transaction, all code will be treated as a do-or-die situation. If one line fails, they all fail, and any changes that were made are rolled back. See Day 12, "Employing Advanced Data Techniques," for more information on transactions.

 

The possible values for this property are

 

Disabled—Method run without a transaction.

 

NotSupported—No transaction support.

 

Supported—Transactions are supported, but the method isn't run within one.

 

Required—A transaction is required; creates a new transaction.

 

RequiresNew—A transaction is required; creates a new transaction.

TypeID

A unique ID to identify this attribute. Used to distinguish between two attributes that are of the same type.


Deploying Web Services

Deploying Web services is a simple matter. Since the Common Language Runtime handles all management of ASP.NET applications, just copy the appropriate .asmx files, .disco files, and custom business objects to the proper directories. Deploying applications has never been easier!

It's a common practice to include a web.config file for the directory containing the services. Often you'll want to implement security mechanisms for these services so that anonymous users don't come along and take advantage of your work. For example, if you develop a Web service for a company, it will most likely be used to generate revenue. If anyone could come along and use the service, the company would never make any money. Securing the Web service (as we'll learn about tomorrow) prevents this situation, and allows you to control who has access to your services.


Caution

The directory that you're deploying to must be flagged as an Internet Information Server (IIS) application directory. Otherwise, these services won't be executed and won't be exposed to clients.

Any directory you've created that allows ASP.NET pages to function is an IIS application directory.


Creating a Web Service from an Existing Business Object

You can also create a Web service from an existing business object so that you don't need to rewrite all the functionality. However, you must modify the existing object slightly to enable service support.

Let's modify the database business object you created in yesterday's lesson, "Using Business Objects." You need to do three things to turn this into a Web service: inherit from the System.Web.Services.WebService class, add the WebMethod attribute for the methods you want to expose, and change the OleDbDataReader into a DataSet because the former isn't transferable via XML (more on that later). Listing 16.4 shows this modified class, which is renamed DatabaseService.


Tip

You can leave the database class as-is and simply create a copy of the class in the same file with a slightly different name. (For instance, append the word "service" to the end.) Only the class that inherits from WebService will be exposed as a service. This allows you to create multiple versions of an object in one file!


Listing 16.4 Modifying Your Database Business Object for Use as a Service

1  Imports System
2  Imports System.Data
3  Imports System.Data.OleDb
4  Imports System.Web.Services
5
6  Namespace TYASPNET
7
8    Public Class DatabaseService : Inherits WebService
9     private objConn as OleDbConnection
10     private objCmd as OleDbCommand
11
12     public function <WebMethod()> SelectSQL(strSelect as _
13       string) as DataSet
14       try
15        objConn = new OleDbConnection("Provider=" & _
16          "Microsoft.Jet.OLEDB.4.0;" & _
17          "Data Source=H:\ASPNET\data\banking.mdb")
18        dim objDataCmd as OleDbDataAdapter = new _
19          OleDbDataAdapter(strSelect, objConn)
20
21        Dim objDS as new DataSet
22        objDataCmd.Fill(objDS, "tblUsers")
23        return objDS
24       catch ex as OleDbException
25        return nothing
26       end try
27     end function
28
29     public function <WebMethod()> ExecuteNonQuery _
30       (strQuery as string) as Boolean
31       try
32        objConn = new OleDbConnection("Provider=" & _
33          "Microsoft.Jet.OLEDB.4.0;" & _
34          "Data Source=H:\ASPNET\data\banking.mdb")
35        objCmd = new OleDbCommand(strQuery, objConn)
36        objCmd.Connection.Open()
37        objCmd.ExecuteNonQuery
38        objCmd.Connection.Close()
39        return true
40       catch ex as OleDbException
41        return false
42       end try
43     end function
44
45    End Class
46
47  End Namespace

On line 4, you import the additional namespace, System.Web.Services. In your class declaration on line 8, you inherit from the WebService class in that namespace. Next, you add <WebMethod()> to the functions you want to expose as services. Finally, in SelectSQL, you change the OleDbDataReader to a DataSet and change the OleDbCommand object into an OleDbDataAdapter. That's all there is to it. Recompile this file with the following command:

vbc /t:library /out:..\bin\TYASPNET.dll /r:System.dll
/r:System.Data.Dll /r:System.Web.Services.dll
/r:System.Xml.dll DatabaseService.vb ..\day15\User.vb

This command compiles the new Database.vb file and User.vb from yesterday's lesson into the library file TYASPNET.dll. You also reference two new DLLs: System.Web.Services.dll and System.Xml.dll. The reason for referencing the first file is obvious; the second reference is included because it contains necessary methods to send the DataSet via XML. For more information on the VB.NET compiler, see yesterday's lesson, "Using Business Objects."


Note

Notice that in this class (the .vb file), you place the attribute <WebMethod()> before the function names. But in the .asmx file, you placed the attribute before the rest of the function declaration. For example, the .vb file uses

		Public function <WebMethod()> ExecuteNonQuery(strQuery _
as string) as Boolean

But the .asmx file uses

		<WebMethod()> Public function ExecuteNonQuery(strQuery _
as string) as Boolean

This is an inconsistency in the Beta 2 version of the .NET Framework. Just be aware of this fact and you should be okay.


The new objects should now be saved in the assembly cache and loaded from it. Let's create the .asmx file that will allow clients to access this object. See Listing 16.5.

Listing 16.5 The .asmx File That Exposes Your Database Service

1  <%@ WebService Class="TYASPNET.DatabaseService" %>

That's all there is to it. You only have to change the class name to reference the database service you just compiled. Save this file as Database.asmx and request it from the browser. You should see the two exposed methods, SelectSQL and ExecuteNonQuery.


Caution

If you use a precompiled object for your Web service, it must be located in the assembly cache in order for ASP.NET to locate and use it.


Click on the SelectSQL method and enter a SQL query in the test portion of the page: Select * FROM tblUsers. Then click the Invoke button. You should see something similar to Figure 16.8.

Figure 16.8
The data returned from your database service.

This XML document defines the structure of the DataSet your service returned. As you scroll down, you'll see the actual data values from the table. The client that receives this XML document can easily transform this object back into a DataSet if necessary.

Returning Data from Services

As demonstrated, Web services can return many types of data. This is because Web services are built on top of XML, which is very powerful for representing data. Even though XML is text-based, it uses a type naming system that allows other applications to determine data types easily.

For example, you know that DataSets are fundamentally represented as XML data in a computer's memory, so it's easy to extrapolate that a DataSet can be sent via XML. XML also has representations for strings, integers, arrays, and DateTimes, among other things. Table 16.2 lists the various data types that Web services can transmit.

Table 16.2 Supported Web Service Data Types

Type

Description

Arrays

Web services can send arrays of any of the types described below, including DataSets, primitive types, classes, and XmlNodes.

Classes

Classes with public properties.

DataSets

The DataSet is internally represented as XML by ADO.NET, so it can be transferred by Web services.

 

Note that DataSets are the only ADO.NET data stores that are transferable. DataReaders and such are not.

Primitives

Primitives include byte, Boolean, char, DateTime, Decimal, Double, GUID, int32, int16, int64, single, uint16, uint32, uint64, and XmlQualifiedName.

XmlNodes

The .NET XmlNode class, an in-memory representation of XML data. See Day 11, "Using XML in ASP.NET."


A Web service can return all of the types described in Table 16.2, but it's more restrictive about which types it will accept as parameters.

When you use SOAP to pass commands and parameters from the client to the service, you can use any of the previously described data types because SOAP is based on XML.

If you use either Http-Get or Http-Post, however, you're restricted to the types that these protocols can handle. That is, you can use a subset of the primitive types and arrays of primitives. Http-Get and Http-Post are also restricted to sending only name/value pairs, which excludes more complex types of data such as classes or DataSets.

That's Not ASP!

Web services are completely new to ASP.NET, so you've been treated to something new today if you're a traditional ASP developer. However, the ideas behind Web services, such as intercommunication of various disparate systems, are similar to COM (Component Object Model) objects. (See yesterday's lesson for more information on COM objects.)

The goal of COM was to allow developers to build applications composed of various components. Because these components relied on the COM protocol to communicate, they could be developed in different programming languages. COM suffered from being confined to a specific platform, though—Windows.

Web services go beyond COM because they don't adopt any proprietary protocols or binary formats of communication between objects. Instead, Web services are completely based on the open standards XML and HTTP, which means they truly allow interoperability between any disparate systems.

The concept of deploying applications over the Internet as services isn't completely new either. Previous attempts, similar to COM, have relied on complex proprietary standards, which limited their usefulness. It's the simplicity of XML and HTTP that makes Web services so effective.

Summary

Today you learned about a new way to deliver applications: over the Internet as Web services. Web services are an integral part of ASP.NET, and they use the XML and HTTP standards to allow components to talk to each other over the Web.

Web services work in three stages: discovery, a description of services, and command communication. Discovery is an optional process that allows clients to find out about a Web service; specifically, where it's located. The service description, provided in an XML-based standard called the Service Description Language, tells clients which methods are available to use remotely and which types of data are expected and returned. Finally, the service and client use these descriptions to send commands to the server and data back to the client.

Three protocols are used for Web service communication: Http-Get, Http-Post, and the Simple Object Access Protocol (SOAP). The first two allow the communication of simple name/value pairs of data. The last one, based on XML, is able to deliver much wider-ranging types of data.

You build Web services in .asmx files, just as you do with business objects. The difference is that you inherit from the WebService class, and all methods that will be exposed as services must use the WebMethods attribute. At a minimum, the .asmx file must contain the following:

<%@ WebService Class="class" %>

The WebService directive tells ASP.NET that this file contains or references a class that should be exposed as a Web service. The class attribute is the name of the class to expose. This class can be either contained within the .asmx file or separately compiled as a business object.

You enable discovery by using .disco files, which are XML documents that contain links to Web service descriptions. These files can be built manually, to define a specific service, or dynamically, to define a group of services available on a server.

Finally, you can view the .asmx files through the browser to see an HTML Description Page, which describes the methods available and allows you to test the functionality directly through Http-Post. You also can see the service description as XML from the .asmx page.

After today, you should be comfortable developing Web services and deploying them on your servers. Tomorrow's lesson will continue the discussion of Web services, and you'll learn how to use them from the client's side.

Q&A

  1. How will Web services affect the average home user?

  1. Chances are that everyday home users won't see them in action for quite some time. Web services require a high-bandwidth connection to the Web, such as DSL or cable modem. Right now, there aren't enough people connected to the Web this way to warrant full-scale use of Web services.

  2. The most likely place you'll see Web services is within businesses that maintain large and strong networks. Information Technology groups will find it much cheaper and easier to manage user workstations because they won't have to install and maintain applications on every single computer.

  1. Is there any way to test a Web service with an Http-Get method? How about with SOAP?

  1. Absolutely. Simply append the function you want to test with any parameters to the address of the .asmx file. For example, you could use the following URL to test the calculator service's add method:

  2. http://localhost/tyaspnet21days/day16/Calculator.asmx/Add?intA=1&intB=2
    

    Separate the function name from the URL with a forward slash, and append the parameters as you would with a querystring. This tests the service via the Http-Get protocol, and the returned XML data will be displayed in the same window.

    You'll learn about using SOAP to test the service tomorrow when you examine using Web services from the client-side.

  1. Do my .disco files need to be named the same way as the Web service files?

  1. No, but it's conventional to do so.

Workshop

This workshop will help reinforce the concepts you've learned in today's lesson. The answers can be found in Appendix A.

Quiz

  1. What's a Web service?

  2. What does SOAP stand for, and what does it do?

  3. What's a service description?

  4. What class (including namespace) must a Web service inherit from?

  5. Write an arbitrary Web method that enables caching and disables session state.

  6. True or false: A Web method can take advantage of intrinsic ASP.NET objects, such as Session and cache.

  7. True or false: A Web method can return a DataSet.

  8. What's the minimum code needed for a .disco file that will enable discovery?

Exercises

  1. Examine the XML service description for the database service you created earlier today. Try to understand each of the tags, recalling the discussions on XML and XML schemas. Note that much of the file describes how the different protocols (Http-Get, SOAP, and so on) are to send and receive data.

  2. Create a Web service that converts one unit of measurement into another. This method should take three parameters: a value, a unit to convert from, and a unit to convert to. Allow the user to convert to and from the following: millimeters, centimeters, inches, feet, meters, yards, miles, and kilometers. Don't forget to test it with the HTML Description page!

  3. (Don't worry if you don't know the exact conversions between units of measurement. Just make something up.)