AddThis Social Bookmark Button

Print

Creating ASP.NET Web Services, Part 1
Pages: 1, 2, 3, 4

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.

Pages: 1, 2, 3, 4

Next Pagearrow