Creating Web Services

This first example of a Web Service is fairly simple. Suppost you have written a function that reports the number of shopping days until Christmas. This is generally useful knowledge which could be of interest to other sites which might wish to supply this same information to their applications. You decide, then, to package this function as a Web Service and make it available to other sites. They might pay big bucks to access your function rather than having to write their own original code.

Initially, this function is written for local consumption. It is coded for execution from this page to produce the following display.


Number of shopping days until Christmas: 323

Figure 11-19. Using a local function to report number of shopping days until Christmas.
<SCRIPT Runat="Server">

Sub Page_Load
  Page.DataBind()
End Sub

Function GetShoppingDays()
	
  Dim ShoppingDays As Integer
  Dim ChristmasDay As String = "12/24/" & DatePart("yyyy", DateString())
	
  ShoppingDays = DateDiff("d", DateString(), ChristmasDay)
  Return ShoppingDays
	
End Function

</SCRIPT>

Number of shopping days until Christmas: 
<asp:Label Text=<%# GetShoppingDays() %> Runat="Server"/>
Listing 11-34. Code to call function to report number of shopping days until Christmas.

A Label control includes the call to function GetShoppingDays(). The function binds to the control when the page loads through the Page.DataBind() method. The GetShoppingDays() function uses the intrinsic Visual Basic DateDiff() function to report the number of day's difference between the current date (DateString()) and the day before Christmas. The current year is extracted from the current date (DatePart()) and appended to "12/24/" so that this date always reflects the current year.

Creating a Web Service File

In order to convert the GetShoppingDays() function into a Web Service it must be recoded as a Visual Basic class and saved as a .asmx file. This file is shown below with the code needed for a Web Service shown in bold.

<%@ WebService Class="ShoppingDays" %>

Imports System
Imports System.Web
Imports System.Web.Services
Imports System.Xml.Serialization

Public Class ShoppingDays
  Inherits Web Service

  <WebMethod()> Public Function GetShoppingDays() As Integer

    Dim NoShoppingDays As Integer
    Dim ChristmasDay As String = "12/24/" & DatePart("yyyy", DateString())

    ShoppingDays = DateDiff("d", DateString(), ChristmasDay)
    Return NoShoppingDays

  End Function

End Class
Listing 11-35. Code to convert a function to a Visual Basic class saved as ShoppingDays.asmx.

The <%@ WebService Class="ShoppingDays" %> directive identifies this as a Web Service and supplies the name through which it is accessed. The System, System.Web, System.Web.Services, and System.XML.Serialization namespaces are imported to expose classes that ASP.NET requires to enable Web Services; the Microsoft.VisualBasic namespace is imported to expose intrinsic Visual Basic functions—DateDiff() and DateString() in the current example.

The Public Class named ShoppingDays is created as a wrapper for the function and the function is prefixed with <WebMethod()> to expose the function for access through a Web Service. Without the WebMethod() applied to the function it would be accessible only to local pages.

This file is saved with the .asmx extension inside a folder that is accessible from the Web (c:\MyWebServices).

Testing a Web Service

A Web Service can be tested in the browser by entering its local URL. When the Web Service is accessed from a browser the default Web Service Help page is displayed listing all the methods of the service along with a default form for testing them. Of course, this is not how the Web Service will be ultimately accessed. In the end, it needs to be accessible through scripted function calls. In the meantime, the Web Service can be tested through a simple URL.

Assuming your ShoppingDays.asmx file is saved in your server's c:\MyWebServices folder, a URL is issued to the file and the following page is displayed.

Figure 11-20. Accessing a Web Service through a local URL.

Notice the link at the top of the page to GetShoppingDays. This is a link to the named Web Method contained in the Web Service. All methods that originate as Visual Basic functions and are packaged together as a Web Service are shown as links. There is just one method in this case. A click on this link produces the page shown below.

Figure 11-21. Testing a Web Service method.

An "Invoke" button is displayed for testing the chosen Web Method. In this example a click on the button returns the number of shopping days until Christmas. When the button is clicked, a window opens to show the returned value, displayed in XML format.

Figure 11-22. Return of method call to Web Service.

At the time this method was invoked there were 232 shopping days remaining until Christmas.

This particular implementation of the Web Service is not particularly useful, although people who need to know this information certainly can use the URL and get back an XML report. For certain Web Services this may be adequate. The principle purpose behind Web Services, however, is application-to-application communications. The goal is to make a Web Service available in a form that can be accessed as a local function by remote Web pages which need access to the service provided.

NOTE: It is assumed that development of a Web Service takes place on the local development computer, http://localhost. Under .NET Framework 2.0 the Web Service's GET, POST, and SOAP protocols necessary to access Web Services remotely are disabled for security reasons. They work only when using a URL to the http://localhost machine. When accessing a Web Service through a URL to a remote server, or when remote users access your local Web Service through a URL, the following message is produced,

"The test form is only available for requests from the local machine."

indicating that permission is not granted to view the service.

However, if you are a provider of Web Services and wish to permit remote URL access to your services, add the following <webServices> section to your application's web.config file:

<!-- Web.Config Configuration File -->

<configuration>

  <webServices>
    <protocols>
      <add name="HttpGet"/>
      <add name="HttpPost"/>
    </protocols>
  </webServices>

</configuration>

Thereafter, remote users can access a local Web Service through a URL to your site and be presented with the same Web Services test page.

Web Service Namespaces

You might notice in Figure 11-20 that a warning is presented that the Web Service is running under the temporary namespace http://tempuri.org/. This is the default namespace when none is given for a service. All Web Services, however, should be assigned unique namespaces so that conflicts do not exist between the same Web Service name appearing at different Web sites. There could be, for example, a Web Service named ShoppingDays provided through another remote server. So that potential like-named services are not in conflict it is advised that a unique namespace be used when creating the service.

To assign a namespace to a Web Service add a <WebService(Namespace:="url")> entry as preface to the class declaration in the .asmx file. The URL can be any address that makes the class name unique among Web sites. The following namespace has been added to the ShoppingDays class.

<WebService(Namespace:="http://www.dradamsweb.com")> Public Class ShoppingDays
Listing 11-36. Code to add a namespace to a Web Service.

When creating your own Web Services, it is recommended that the Namespace provided be the URL of your own Web Site and that the class name be unique at your site.

Creating a .asmx file and placing it in a Web-accessible directory is all that is required to supply a Web Service that can be accessed from anywhere on the Web. As a user of someone else's Web Service, however, you need to create a proxy class, a Visual Basic class, to consume the remote service.