ONDotNet.com    
 Published on ONDotNet.com (http://www.ondotnet.com/)
 See this if you're having trouble printing code examples


O'Reilly Book Excerpts: Programming .NET Web Services

Creating ASP.NET Web Services, Part 1

Related Reading

Programming .NET Web Services
By Alex Ferrara, Matthew MacDonald

by Alex Ferrara and Matthew MacDonald

In part one in this series of book excerpts from Programming .NET Web Services, learn how to write an ASP.NET HelloWorld Web service application.

Using the .NET Framework, it's easy to get a basic service up and running. In just a few minutes and fewer lines of code, you can put together a simple "Hello World" service without any understanding of HTTP, SOAP, WSDL or any of the several technologies that form the basis for web services. In fact, if you're a Microsoft Visual Studio .NET user, all you need to do to create a simple "Hello, World" service is to open a new Visual C# or Visual Basic ASP.NET Web Service project and uncomment the sample code provided by the template.

In this chapter, you'll learn about ASP.NET, the new Microsoft technology for building web applications and services, and how to use the .NET platform and Visual Studio .NET to create some simple web services. We'll also talk about some of the features of .NET that will get you on the road to developing well-documented scalable web service applications. By the end of this chapter, you'll have a solid understanding of how .NET supports web services and how to use the .NET platform to create them. We'll start with the ubiquitous "Hello, World" example exposed as a web service.

Creating a Web Service: "Hello, World"

In this section, you'll create a simple web service in the "Hello, World" tradition. Through this brief example, you'll see how easy it is to use ASP.NET to create a working web service (with a text editor or with VS.NET) and learn about the basic technologies behind .NET web service.

Creating a Web Service with Inline Code

While Visual Studio .NET provides a feature-rich integrated development environment for .NET development, it's not required to create .NET web services. Applications can also be created using your favorite text editor and the command-line tools that ship with the .NET Framework SDK. Here, we use Notepad as a text editor, but you should feel free to use whatever editor you're most comfortable with (Emacs or vi).

If you chose to develop with a text editor, you must place all of your code in one or more text files, assign them each the file extension .asmx and place them in an IIS folder on a server or workstation that has the .NET Framework installed. Once you save the code to a folder served by the IIS web server, it's ready to run--that's it! How you get the file to your web server is your business. If you're running IIS locally on your workstation (and you've installed the .NET Framework), this is as simple as saving the file to a suitable location on your local drive (e.g., c:\inetpub\wwwroot\). If you're using a remote server (in which case there's no need to have the .NET Framework installed locally), you might have to use FTP or a network share instead (more about this later).

Once you've chosen a text editor and file location, all that's left is to write the code.

Example 2-1 lists the code for a C# version of the ubiquitous "Hello, World" application; unlike the classic desktop version, this one delivers its familiar message over the Web through an exposed method called HelloWorld(). To identify the class and method as a web service to the compiler, this code uses some special notation. It also includes an ASP.NET directive at the head of the file.

To create a C# version of the HelloWorld web service, enter the code from Example 2-1 exactly as it appears, and save the file to your web server under the c:\inetpub\wwwroot folder (or whatever folder is the web root folder for your system) with the name HelloWorld.asmx.

Example 2-1. HelloWorld: C# web service

<%@ WebService Language="C#"
Class="ProgWS.Ch02.HelloWorldService" %>
using System.Web.Services;
namespace ProgWS.Ch02
{
  public class HelloWorldService: WebService 
  {
    [WebMethod]
    public string HelloWorld()
    {
      return "Hello World";
    }
  }
}

In the following sections, we'll explain the standard elements of this web service source file and then show you how to test it.

The WebService directive

Example 2-1 begins with a WebService directive, an ASP.NET statement declaring that the code that follows is a web service:

<%@ WebService Language="C#" Class="ProgWS.Ch02.HelloWorldService" %>

TIP: The WebService directive is similar to the Page directive that begins most .aspx pages.

For the HelloWorld web service to work, you must assign values to two WebService directive attributes: Language and Class.

The required Language attribute lets .NET know which programming language the class has been written in. As you might guess, the acceptable values for the language attribute are currently C#, VB, and JS for JScript.NET.

The Class attribute, also required, tells ASP.NET the name of the class to expose as a web service. Because a web service application can comprise multiple classes, some of which may not be web services, you must tell .NET which class to expose, a step analogous to declaring a Main() method to indicate the entry point of a .NET console application or component. Note that even if your web service contains only one class, setting this attribute is required.

The using directive: importing .NET namespaces

The next line in the example is a using statement that tells the compiler to alias the System.Web.Services namespace to the local namespace. For C#, this directive is:

using System.Web.Services;

This directive allows you to refer to objects in the System.Web.Services namespace without having to fully qualify the request. This statement is optional, but if it is not included, every reference to an object in this namespace must be fully qualified. An example is the next line, which is our class declaration. With the using statement, it looks as follows in C#:

using System.Web.Services;
public class HelloWorldService: WebService

Without the using statement, it would have to be written fully qualified:

public class HelloWorldService: System.Web.Services.WebService

Note: Importing a namespace does not give you access to any of the additional namespaces that appear to be nested in that namespace. In other words, if you were to import the System.Web namespace, you would not be able to refer to the System.Web.Services.WebService class as Services.WebService. While a namespace like System.Web.Services may "appear" to be nested in the System.Web namespace, that is not the case. They are implemented as two different assemblies that bear little relation to each other aside from a partial name sharing. The apparently hierarchical nature of the .NET Framework's namespaces exists in name only as an organizational convenience and has no bearing on class structure.

The namespace keyword

.NET allows you--and Microsoft encourages you--to put the classes of an application into a unique namespace. In C#, this is done with the namespace keyword and the following syntax:

namespace name
{
... type declaration ...
}

In Example 2-1, the HelloWorldService class is placed in the ProgWS.Ch02 namespace with the following statement:

namespace ProgWS.Ch02
{...
}

Namespaces can contain definitions for classes, interfaces, structs, enums, and delegates, as well as other namespaces. In addition, the source code for objects in a namespace does not have to be stored in the same file--it can span multiple files.

Note: For Java programmers: a namespace is similar to a package. However, unlike a package, in a namespace there are no directory structure requirements, because all of the source code is presumed to be in the same directory or a global assembly cache.

Namespaces provide a means of grouping pieces of code that might be written and maintained by other developers. When the class definitions of your web service exist within a namespace, you must specify the namespace along with the class name in your WebService directive as in Example 2-1:

<%@ WebService Language="C#" Class="ProgWS.Ch02.HelloWorldService" %>

This line tells ASP.NET to look for the class HelloWorldService in the namespace ProgWS.Ch02.

The WebService class

At the heart of Example 2-1 is a class called HelloWorldService. This class is a subclass of System.Web.Services.WebService. By inheriting from the WebService class, a web service gains direct access to the ASP.NET intrinsic objects, such as Application and Session, just like any other ASP.NET application.

TIP: While inheriting from the WebService class is a common approach for creating a .NET web service, it is by no means necessary. You can rewrite the previous examples without this inheritance, and your service will run just fine. However, if you need access to the Application and Session objects without inheriting from WebService, you'll need to use the System.Web.HttpContext object explicitly, as we'll explain in a later chapter.

The WebMethod attribute

Related Reading

Programming .NET Web Services
By Alex Ferrara, Matthew MacDonald

The HelloWorldService class exposes a single method, the public method HelloWorld, which takes no arguments and returns a string containing the text "Hello World". To expose a method as a part of a web service, you must decorate it with the WebMethod attribute, which tells the compiler to treat it as such. Any method marked with the WebMethod attribute must be defined as public. Class methods exposed as web services follow the same object-oriented rules as any other class, and therefore methods marked private, protected, or internal are not accessible and will return an error if you attempt to expose them using the WebMethod attribute. For additional details, see "The WebMethod Attribute" later in this chapter.

The neat thing about this simple example is that you've created a full-blown web service out of an arbitrary method. You could just as easily have substituted a method that retrieves a record from a data store or a method that wraps a COM object. Additionally, you could have used any of the languages supported by the .NET Framework for this implementation and, then, as you will see later, used any .NET or non-.NET language in a client application. By inheriting from the System.Web.Services.WebService class, you are able to take advantage of an API that insulates you from the underlying SOAP/XML message exchanges.

To put this web service to work, all you need to do is copy it to the web server just as you would any other resource, whether it's an image, HTML file, ASP page, or another resource. Once you've done that, the web service is ready to be used by a consumer application, a process we'll look at in detail in Chapter 3. This ease of deployment is the main benefit of inline coding; perhaps the biggest drawback is that your presentation code and business logic are lumped into the same file, which can make working with large projects difficult to manage. Let's take a look at how Visual Studio .NET can be used to create and deploy this web service without stepping outside its Integrated Development Environment by using the so-called code-behind approach.

Assemblies

We said that a namespace is a container for types such as classes, interfaces, structs, and enums. We also said that the source code for objects in a namespace does not have to be stored in the same file, but can instead span multiple files. When the set of source code constituting a namespace is compiled into a library, this library is called a managed DLL, or, more commonly, an assembly. Assemblies are the building blocks of .NET applications and the fundamental unit of deployment. They comprise a collection of types and resources that provide the CLR (Common Language Runtime) with the information it needs to be aware of type implementations. Their contents can be referenced and used by other applications using Visual Studio .NET or a .NET command-line compiler.

Creating "Hello, World" with Visual Studio .NET

While Notepad is an adequate tool for creating simple services, Microsoft's new development environment, Visual Studio .NET (VS.NET), provides a world of features to aid you in creating complex web services. Visual Studio .NET also provides the quickest path to getting a web service up and running, apart from the time it takes to install all or part of the more than 1.8 GB (compressed) of installation files required to run Visual Studio .NET. This section takes you through the process of creating the "Hello, World" service using Visual Studio .NET.

Setting up VS.NET for the web service project

To make use of the automation in VS.NET, you must first configure it to communicate with your web server. You can use either FrontPage Extensions or Universal Naming Convention (UNC) file shares. To keep things simple, we'll assume you have installed IIS on your local workstation. Here's what you need to do to set up VS.NET for your first web service. We go into detail on FrontPage Extensions and UNC file shares later in this chapter (see "Deploying a Web Service.")

Microsoft FrontPage Server Extensions are the easiest to configure and a good choice for the simple web services in the next two chapters. FrontPage Extensions can be installed as a part of IIS, or alternatively downloaded for free from the MSDN site at http://msdn.microsoft.com. For this example, we're using a Windows 2000 workstation, IIS 5, and FrontPage 2000 Server Extensions, version 4.0.2.4426. While any version of the Extensions will work, the configuration process varies greatly among them and the steps outlined here may not work with your version.

Once you've installed FrontPage Server Extensions on your local workstation (i.e., the workstation hosting IIS), open the Internet Services Manager from the Start -> Programs -> Administrative Tools menu so that you can configure a FrontPage web. Right-click on Default Web Site and select All Tasks -> Configure Server Extensions from the dialog box. You will be taken through a brief configuration wizard that asks you configuration questions. Once the server extensions have been installed, you're ready to create a web service project in Visual Studio .NET.

TIP: With Windows XP, you reach Administrative Tools and the IIS Manager through he Control Panel.

Creating a C# web service project

Visual Studio 6.0 users will find the layout of Visual Studio .NET familiar enough that they can get working without much assistance. We'll help users who are new to Visual Studio. Users new to Visual Studio .NET can also rely on its extensive built-in Help feature.

To create a new web service, fire up Visual Studio .NET and either select the New Project button on the default Start Page or click File -> New -> Project on the main Visual Studio .NET menu bar. The Visual Studio project model is the same as earlier versions, in that a file can be part of a project, and a project part of a solution. A solution is the outermost container, containing zero or more projects. After selecting an option to create a new project, you'll see the screen in Figure 2-1.

Figure 2-1. Creating a new Visual Studio project

Figure  

Here you have the option to create a variety of project types from templates. Under Visual C# Projects, one template option creates an ASP.NET web service, while our examples use the C# language, the same option also available as a Visual Basic project, and similar options for Managed C++ exist as well. In addition to selecting a project language and template, you must specify a project name and location. The location fior the HelloWorldService should be the URL of the IIS web server you just configured to work with FrontPage Extensions (e.g., http://localhost). For this example, we'll use the project name "HelloWorldService."

Once you click OK, the IDE (Integrated Development Environment) creates a new solution and project and automatically populate the project with several files. The IDE will also create a virtual folder under IIS with the same name as the project name, which, in this case, is HelloWorldService.

Exploring the solution and project

The contents of your new project are displayed in the Solution Explorer window, which should appear on the right side of the VS.NET IDE, as shown in Figure 2-2.

Figure 2-2. The Visual Studio .NET Solution Explorer

Figure  

If the Solution Explorer is not visible, you can open it by selecting Solution Explorer from the View menu (or pressing Ctrl-Alt-L).

When you create a new project without specifying the name of an existing solution, VS.NET creates a new solution whose name is the same as the one you chose for your project. You can see in Figure 2-2 that, in this case, a solution named HelloWorldService has been created; it contains one project, also called HelloWorldService.

Visual Studio .NET also automatically creates several assembly references and files, which are also displayed in the Solution Explorer, as shown in Figure 2-3. In this example, VS.NET has included assembly references to the System, System.Data, System.Web, System.Web.Services, and System.XML namespaces. (The System.Data and System.XML assembly references are not necessary for this example, so you can remove them if you'd like, but there's no real benefit to doing so other than simplicity.)

Figure 2-3. Displaying all files in VS.NET Solution Explorer

Figure  

The five other files that appear in Figure 2-3 are AssemblyInfo.cs, Global.asax, HelloWorldService.vsdisco, Service1.asmx, and Web.config. The only file you really need to create the web service is the .asmx file, which we'll discuss in the next section. The four other files provide additional features and functionality that will help you as you build more complex services, but none of them are necessary for this example. In fact, you can delete all of the non-.asmx files and the service will run just fine (we don't recommend this). Here's a brief explanation of of each of these.

AssemblyInfo.cs
An information file that provides the compiler with metadata (name, version, etc.) about the assemblies in the project.
Global.asax
Customizable to handle application-level events (e.g., Application_OnStart).
HelloWorldService.vsdisco
An XML file used for dynamic discovery of web services. The DISCO specification has been superseded by WS-Inspection and is discussed in Chapter 10.
Web.config
An XML file containing configuration information for the application.

Exploring the .asmx file and service design view

The most important file in our example is the sample service page named Service1.asmx. If you open the page by double-clicking it, Visual Studio .NET displays a blank design page in its main window. If we were dealing with an .aspx ASP.NET web application, this design page could be used to design the user interface for the page, but since we're developing an .asmx web service that will be consumed by a machine rather than a person, this design view is not as useful to us. If you try to add a Windows form component, you'll get an error ("Object reference not set to an instance of an object"), because the web service design view doesn't know what to do with the component. Unlike an ASP.NET web form project, an ASP.NET web service project doesn't include the plumbing to support Windows form components.

You can use the design view to add preprogrammed components to your service from the Visual Studio .NET Toolbox, but you can't do much beyond adding these items, which is just as easily done directly through the code view page (Service1.asmx.cs). Perhaps Microsoft or another vendor will provide more powerful support for drag-and-drop web service design using business-logic components at some point, but as of today, the design view is not very useful. Instead, you can view the source code of your service by right-clicking on the Service1.asmx file in Solution Explorer and selecting View Code. At this point, you'll also want to rename the Service1.asmx file to something more appropriate to the project. You can do this by right-clicking the file in Solution Explorer and selecting Rename from the menu. Change the name to HelloWorldService.asmx.

Displaying all files in Solution Explorer

The .asmx.cs file is not displayed by default in Solution Explorer. To see it, select Show All Files from the Project menu tab (there's also an icon at the top of Solution Explorer to do this). The Solution Explorer view will change to look like Figure 2-3.

This new view displays all of the files associated with the HelloWorldService project. Notice that the Service1.asmx file now has a tree expander icon to the left of it. Click on the icon, and you'll see another file beneath the Service1.asmx file called Service1.asmx.cs. Elsewhere, you'll also notice a folder called \bin, which is used to store the project's compiled assemblies generated by Visual Studio .NET.

Understanding the autogenerated service code

When you create a new ASP.NET web service project, Visual Studio .NET generates some boilerplate code to get you started. The contents of the source file HelloWorldService.asmx.cs should resemble that reproduced in Figure 2-4.

Figure 2-4. Visual Studio .NET boilerplate code

Figure  

This boilerplate code begins by importing several namespaces generally required for web services and by automatically generating namespace and class definitions. In this example, the namespace and class definitions are HelloWorldService and Service1, respectively.

The namespace definition is generated based on the project name, but you will probably want to change to something more suitable (in this case, we're going to continue to use ProgWS.Ch02) depending on your application. The service name is always autogenerated as Service1. Change this to something more appropriate for your application (in this case, we're using HelloWorldService), but you should also remember to change the name of the .asmx page to mirror your service name. Your service will run just fine if the names don't match up, but keeping the naming consistent can help make managing your service easier, particularly if you have a project with a large number of services.

The imported namespaces at the beginning of the code are provided as a convenience, and some of them are unnecessary. Specifically, the System.Data, System.Collections, and System.Diagnostics namespaces are not used at all. The classes of the System.ComponentModel namespace are used only by the web service designer methods, InitializeComponent() and Dispose(), which work in conjunction with a private member variable of type IContainer called components. To see these methods, you need to expand the Component Designer Generated Code region. Since you're most likely not going to need the (limited) features of the web service design view, you can clean house by deleting the entire region. You will be left with code that looks like the following (some comments have been removed to shorten the listing).

using System;
using System.Web;
using System.Web.Services;
 
namespace ProgWS.Ch02
{
  public class HelloWorldService : System.Web.Services.WebService
  {
    public HelloWorldService() {}
    // WEB SERVICE EXAMPLE
    // The HelloWorld() example service returns the string Hello World
    // To build, uncomment the following lines, then save and build the project
    // To test this web service, press F5
 
    //[WebMethod]
    //public string HelloWorld()
    //{
    //return "Hello World";
    //}
}
}

This code should look familiar since it is nearly identical to the code shown in Example 2-1. All you need to do to make it look like the earlier example is to remove the comments in front of the HelloWorld() method and [WebMethod] attribute.

Notice, however, that the WebService directive that was present in the inline code example is missing:

<%@ WebService Language="C#" Class="ProgWS.Ch02.HelloWorldService" %>

Recall that this directive is required to tell the compiler which class file to use as the entry point for the web service. So where is it? When you wrote the inline code example, you included both the directive and the source code for the HelloWorld class in the same file. By contrast, when Visual Studio .NET creates web service code, it separates the WebService directive and the source code using an approach known to ASP.NET developers as code-behind.

Understanding the code-behind model

The code-behind approach to programming web services (as well as ASP.NET web applications) involves separating the WebService directive from the supporting C# code. In this model, the .asmx page contains only one line, the WebService directive, while the supporting source code is placed on its own page, which, in the case of C#, has the file extension .asmx.cs, as in the preceding example. This page must be compiled into an assembly and placed in the \bin directory of your web service before the service can be used. Visual Studio .NET takes care of this process for you automatically when you build your project.

When you send a request to your web service for the first time, ASP.NET reads the WebService directive to find out the name of the class file containing its supporting logic. ASP.NET knows to look for the compiled class in an assembly in the \bin directory of the project. If there are multiple assemblies in the \bin directory, ASP.NET will look through each of them until it finds the appropriate class.

One of the advantages to storing your code in a compiled form is that source code is not left lying around on your production web servers. A malicious user who gains access to the server hosting your application will not easily be able to steal your code (we say "easily" because there are tools for decompiling MSIL). The disadvantage to using the code-behind model is that deployment requires an additional step--compiling the source code--which is not necessary for inline code.

The CodeBehind Attribute

If you find and view the .asmx page that VS.NET automatically generates and places on your server, you'll notice that the WebService directive includes an additional attribute called CodeBehind. (Unfortunately, you cannot view this .asmx page from Visual Studio .NET; instead, you'll need to look at the file placed on your web server in the c:\inetpub\wwwroot\HelloWorldService folder). In our example, it looks like this (except it's all on a single line):

<%@ WebService Language="c#"
    Codebehind="HelloWorldService.asmx.cs"
    Class="ProgWS.Ch02.HelloWorldService" %>

This unfortunate choice for an attribute name often confuses developers new to ASP.NET, who often assume that it is used in some way by ASP.NET to locate the code-behind file (indeed, the Microsoft Visual Studio documentation would lead you to believe this to be the case). In fact, this is not the case. This attribute is a Visual Studio .NET-specific attribute and is used by VS.NET to match the .asmx page to the associated source code file. This attribute has nothing to do with ASP.NET. In fact, ASP.NET completely ignores this attribute when processing a page request.

TIP: Visual Studio .NET is not designed to support the inline coding model. It's possible for you to use it, but we certainly do not recommend it: you cannot directly create an inline web service in Visual Studio .NET, because when you create a new web service, by default, Visual Studio .NET creates separate .asmx and class files.

To create an inline service using VS.NET, you must create a new text file and change its extension to .asmx. Creating an .asmx page in this manner forces you to write your code in the Visual Studio .NET HTML editor, not the code editor, which does not provide support for color coding, Intellisense, or many of the debugging features. In addition, because the code in the page is not compiled into the project assembly, compile-time errors are not caught until the page is run.

Building the service

Because Visual Studio .NET uses the code-behind model, simply posting the source pages to the server as in the inline example will not work. If you do so, you will get an error when you try to access the service. Instead, it's necessary to save your .asmx page to the server and compile your source code, saving it to the project's \bin directory. VS.NET automates this process for you through its build feature. Once your application is complete, select Build Solution from the Build menu (or press Ctrl-Shift-B) and VS.NET will compile your web service and transfer the .asmx page and associated compiled assembly to the web server for you. If any errors result from the compile, VS.NET will display them in a panel labeled Output at the bottom of the IDE. Once you have successfully built the web service, it's ready to be used.

Testing the Service

Unlike Active Server Pages, web services are not designed to be viewed in a browser. Instead, web services are consumed by a client application using protocols such as HTTP GET/POST, SMTP, or SOAP over HTTP (see Chapter 3 for more information on consuming web services). Some of these protocols, such as SOAP, are more appropriate for server-to-server communication, while others, such as HTTP GET, are more frequently associated with the model of traditional web page access.

A web service that uses HTTP GET as a transport protocol can be accessed in much the same way as a regular web page. All that is necessary to access such a page is to point a web browser to the service endpoint. In our example, the endpoint comes is an .asmx page. But how do you know which protocols HelloWorldService will support, since there is no mention of HTTP or SOAP in the example code? The answer is that, by default, all .NET web services try to support HTTP GET, HTTP POST, and SOAP. We say "try," because in many cases the web service may be too complex for HTTP GET support. Additionally, because web services are applications that expose functionality to web service clients, and as a result have no required graphical user interface, .NET provides a canned web service test page that is displayed when you point your browser to an .asmx page. If you open a browser and type in the URL of the .asmx web service you just created, you'll see the IE test page shown in Figure 2-5.

Figure 2-5. The HelloWorldService test page

Figure  

The page in Figure 2-5 is generated by the .NET HTTP runtime each time it receives a request for an .asmx page. The page template is itself an ASP.NET .aspx page named DefaultWsdlHelpGenerator.aspx and is stored in the \WINNT\Microsoft.NET\Framework\[version]\Config directory on the server that hosts the web service. This page operates just like any other .aspx page (remember that this is the extension for ASP.NET pages) and can be easily customized.

The test page displays the HelloWorldService service name along with the HelloWorld() method and a link to the service description. The service name and any additional information about this service are retrieved through a process called reflection, which uses the System.Reflection namespace to reveal information about existing types via metadata. In fact, if you look at the Page_Load function for the DefaultWsdlHelpGenerator.aspx page (again, in the \WINNT\Microsoft.NET\Framework\[version]\Config directory on the hosting server), you'll see how this process works. If our service contained additional methods that were callable via HTTP, they would be listed as links here as well.

Viewing the Service Description

The runtime also automatically creates a service description from the .asmx page, an XML document that conforms to a specification called Web Service Description Language, or WSDL (pronounced "Wiz-Duhl"). If you click the service description link, you'll see the WSDL page. This page can also be viewed in a browser by appending ?WSDL to the page URL, as in HelloWorldService.cs.asmx?WSDL. The service description for our service is shown in Figure 2-6.

Figure 2-6. The HelloWorldService description

Figure  

You can see that the WSDL document includes information about the service namespaces, protocols supported, data types used, and web methods exposed in an XML-based format. This type of information is particularly important for an application looking to use our service, as you'll see in the next chapter.

The WSDL specification is a linchpin of sorts for the various web service development platforms. As you'll see in Chapter 11, where you'll learn about web service interoperability, web service development platforms must all abide by the same version of WSDL as well as the same version of SOAP if they are to work together (actually, WSDL is not an absolute requirement, but it is necessary for automatic proxy generation, as you'll see in Chapter 3). The version of WSDL we discuss in this book, 1.1, is currently supported by .NET and most other web service implementations (e.g., SOAP::Lite, Apache Axis).[1] The .NET Framework currently implements SOAP 1.1.

Getting back to the service test page: if you mouse over the HelloWorld link, you'll see the destination URL:

http://localhost/HelloWorldService.cs.asmx?op=HelloWorld

By clicking this link, you call the .asmx page, passing a parameter called op (standing presumably for operation) along with the name of the service. This action is the same as calling the HelloWorld web method of the web service using HTTP GET. The output page is shown in Figure 2-7.

Figure 2-7. The HelloWorldService invocation page

Figure  

Here you'll see the name of the service and method along with a button to test the service. Through reflection, the logic in the DefaultWsdlHelpGenerator.aspx test page is able to determine the signature of our HelloWorld method. Because our web method takes no arguments, the page need provide only a button for invocation. If our method had a different signature--for example, if it reads a string of text--the .aspx help page would also provide a text box to capture this string and pass it, using HTTP GET, to the web method when the form was submitted. This text box method works fine for simple data type arguments, but if the web method were to require an object, this approach would not work.

Beneath the Invoke button, there are also sample service interactions for SOAP, HTTP GET, and HTTP POST. We'll talk about some of the other methods of consuming web services in Chapter 3, but for now, note that on the source, the page is still using HTTP GET to invoke our service.

<form 
 action='http://localhost/HelloWorldService/HelloWorldService.cs.asmx/HelloWorld' 
 method="GET">                        
...
</form>

Invoking the Web Method

You can invoke the web method using the IE test page by opening a web browser and navigating to the service's URL. You will see a page listing the service's operation, which should be HelloWorld. Click the HelloWorld operation to navigate to the web method invocation page. This is a page that allows you to test the operation by clicking a button labeled Invoke. Click the button to invoke the service.

Invoking the example service produces the results shown in Figure 2-8.

Figure 2-8. HelloWorldService output

Figure  

You know that web services are a means of communicating between servers using XML, so it should come as no surprise that the output of our service is nothing more than an XML document--and a short one at that! Had you used SOAP to access the service, you would have received a message in SOAP format; however, since IE isn't designed to either write or read SOAP messages by itself, you're limited to using HTTP GET and POST.

The response document begins with the following XML declaration:

<?xml version="1.0" encoding="utf-8" ?>

which identifies the document as an XML document and identifies the encoding of the document to be UTF-8 Unicode. While the encoding type may vary, all XML processors are required to support UTF-8 and UTF-16 Unicode encodings.

The first and only element in the output document is an element called string, which contains the output of our method and has one attribute called xmlns:

xmlns="http://tempuri.org"

This namespace declaration specifies that all unprefixed elements in this document come from the namespace tempuri.org.

In the next installment, learn about the WebService attribute.

Alex Ferrara is Chief Technology Officer at U-Inspire, a provider of on-line business training and motivational services, and head of Boston Technical, a consulting arm of U-Inspire that specializes in .NET application development.

Matthew MacDonald is a developer, author, and educator in all things Visual Basic and .NET. He's worked with Visual Basic and ASP since their initial versions, and written over a dozen books on the subject, including The Book of VB .NET (No Starch Press) and Visual Basic 2005: A Developer's Notebook (O'Reilly). His web site is http://www.prosetech.com/.

Programming .NET Web Services

Related Reading

Programming .NET Web Services
By Alex Ferrara, Matthew MacDonald

Copyright © 2009 O'Reilly Media, Inc.