The ASP.NET Web Services Infrastructure

Team-Fly    

 
.NET and COM Interoperability Handbook, The
By Alan Gordon
Table of Contents
Chapter Ten.  XML Web Services

The ASP.NET Web Services Infrastructure

ASP.NET is completely rearchitectured from the ISAPI model for server-side programming using IIS and HTTP. The ISAPI model allowed you to create your own DLLs that would receive HTTP requests, could perform custom processing, and return a response. ASP (the predecessor to ASP.NET) was implemented as an ISAPI DLL that received requests from files with a .asp extension, compiled the script contained in these pages, and returned the result of the script, along with any surrounding HTML. The architecture of ASP.NET is far more flexible. It allows you all the power of ISAPI, with a much simpler programming model and the ability to support both Web Forms and Web services. At a high level, the ASP.NET architecture is as shown in Figure 10-2.

Figure 10-2. The ASP.NET architecture.

graphics/10fig02.gif

ASP.NET uses an extensible HTTP pipeline. When you first install ASP.NET, it adds a number of standard file extensions to the IIS metabase. Perform the following steps to view these file extensions on your machine:

  1. Select Programs Administrative Tools Computer Management from the Start menu. The Computer Management MMC snap-in appears.

  2. Open the Default Web Site node in the tree under Services and Applications Internet Information Services.

  3. Right-click on a virtual directory beneath the Default Web Site node and select Properties from the context menu. The IIS Application properties dialog appears.

  4. On the Virtual Directory tab of the properties dialog, click the Configuration button. The Application Configuration dialog appears as shown in Figure 10-3.

    Figure 10-3. The IIS Application Configuration dialog.

    graphics/10fig03.jpg

You can see that there are a number of familiar .NET file extensions, including .aspx, .config, .soap, .cs, and .vb. There are two new ones that are XML Web service related , .asmx and .ashx., which I talk about shortly and which are mapped to the following executable: D:\WINNT\Microsoft.NET\Framework\v1.0.3705\aspnet_isapi.dll .

Note

The .asp file extension still maps to the ASP runtime at D:\WINNT\System32\inetsrv\asp.dll.


When IIS receives an HTTP request for a file with one of these extensions, it funnels the request into the HTTP pipeline shown in Figure 10-2. The aspnet_isapi.dll , whichlike all ISAPI DLLsruns in the same process as the IIS service (inetinfo.exe), forwards the request using a named pipe to the ASP.NET worker process (aspnet_wp.exe). The HTTP pipeline runs in the ASP.NET worker process.

The request first goes to an HttpRuntime object, which examines the request and figures out which application it was sent to. The HttpRuntime then uses an HttpApplicationFactory object to create an HttpApplication object to handle the request. The HttpRuntime object also creates an HttpContext object that, among other things, contains the request (an instance of the HttpRequest class) and the response (an instance of the HttpResponse class) and passes it to the HttpApplication object. An HttpApplication object is created to handle each request, so the HttpApplicationFactory object pools HttpApplication objects to maintain optimal performance. An HttpApplication object holds a collection of HttpModules, and it also uses an HttpHandlerFactory object to create an HttpHandler object.

HttpHandlers are the endpoints of the ASP.NET HTTP pipeline. They will consume the request and produce a response. Like HttpApplication objects, one HttpHandler object is created for each request, and they are pooled for optimal performance. The HttpApplication object uses different HttpHandlers to process requests, depending on the file extension of the request. You can also create your own HttpHandlers by providing an implementation of the System.Web.IHttpHandler interface and then adding an entry to a configuration file to specify which file extensions the System.Web.IHttp-Handler implementation should be used with.

HttpModules are filters that can examine and modify the contents of a request, but do not consume the request. They are the successor to ISAPI filters. Standard HttpModules are used to implement security and session management. You can also create your own modules by creating a class that implements the System.Web.IHttpModule interface. Let's take a more in-depth look at HTTP handlers and modules.

HTTP Handlers

ASP.NET comes out of the box with a set of standard HTTP handlers that implement both Web Forms and Web services. You can view the mapping of file extensions to HttpHandlers (actually, the mapping is to handler factories) by looking at the machine.config file, which you can find at [ WINNT_Directory]\Microsoft.NET\Framework\[Version]\CONFIG where [WINNT_Directory] is the location of the Winnt directory on your machine and [Version] is the version number of .NET Framework. On my machine, the complete path is D:\WINNT\Microsoft.NET\Framework\v1.0.3705\CONFIG .

If you search for the HttpHandlers subelement in this configuration file, you will see the following:

 <httpHandlers> <add verb="*" path="trace.axd" type="System.Web.Handlers.TraceHandler"/> <  add verb="*" path="*.aspx"  type="System.Web.UI.PageHandlerFactory"/> <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory"/>  <add verb="*" path="*.asmx"   type="System.Web.Services.Protocols.WebServiceHandlerFactory,   System.Web.Services, Version=1.0.3300.0, Culture=neutral,   PublicKeyToken=b03f5f7f11d50a3a" validate="false"/>  <add verb="*" path="*.rem" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/> <add verb="*" path="*.soap" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/> <add verb="*" path="*.asax" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.ascx" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.config" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.cs" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.csproj" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.vb" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.vbproj" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.webinfo" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.asp" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.licx" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.resx" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.resources" type="System.Web.HttpForbiddenHandler"/> <add verb="GET,HEAD" path="*" type="System.Web.StaticFileHandler"/> <add verb="*" path="*" type="System.Web.HttpMethodNotAllowedHandler"/> </httpHandlers> 

Notice the handlers for the .aspx and .asmx file extensions, which I have shown in bold. The entry for the .aspx extension shows that the ASP.NET Web Forms files are handled by a class called System.Web. UI .PageHandlerFactory . This class parses and compiles the aspx file (if it hasn't been compiled already) and renders the result as HTML. The handler for asmx files is the one that implements most of the ASP.NET Web services' functionality. The asmx files are handled by a class called System.Web.Services.Protocols.WebServiceHandlerFactory . The following code shows an example asmx file for a very simple Hello World XML Web service:

 <%@ WebService Language="C#" class="Hello" %> using System.Web.Services; class Hello {     [WebMethod]     public string HelloWorld()     {         return "Hello XML Web Service World!!!";     } } 

Note

You will soon see how to deploy and use an XML Web service.


The WebServiceHandlerFactory handler parses the asmx file. The WebService header at the top of the file tells the handler that the code for the Web service was written in C# and that the class that contains the business logic for the Web service is called Hello . In this case, the code for the Hello class is contained directly in the asmx file, but later you see how you can use the code-behind directive to put the business logic of the Web service into a separate file. The handler will invoke the C# compiler to compile the code for the Web service. It then caches the compiled assembly and uses reflection to find the method that the request is trying to invoke. All methods that will be exposed through the Web service must be marked with the System.Web.Services.WebMethod attribute as shown previously in the asmx file. The handler will then call the requested method, take the result, and send it to the client as an HTTP response.

Thanks to the ASP.NET infrastructure, your job as an XML Web service developer is incredibly easy. Simply create a file with the .asmx extension and then specify what language you are using and the name of the class that contains the implementation of the XML Web service. Define the business logic of your Web service as a class in your selected language, adding the System.Web.Services.WebMethod attribute to the methods that you want to expose through the Web service. You then create an IIS virtual directory for your Web service and add the asmx file to the virtual directory. Then add the assembly that contains the class that implements the business logic of the assembly to a bin directory beneath your virtual directory (or to the GAC).

The ASP.NET Web services infrastructure is fully extensible. If you don't like the handlers that ASP.NET provides out of the box, you can create your own by implementing the System.Web.IHttpHandler interface. The System.Web.IHttpHandler interface is defined as shown here:

 interface IHttpHandler {         void ProcessRequest(HttpContext ctx);         bool IsReusable { get; } } 

Let's define the Hello World Web service as a custom HTTP handler using the .ashx file extension. If you refer back to the machine.config file, you will see that there is an HTTP handler for files with the extension .ashx.

 <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory"/> 

The handler for this file extension compiles and calls an implementation of the IHttpHandler interface. Therefore, you can create a Web service by defining an implementation of the IhttpHandler interface as shown here and saving it in a file with the extension .ashx:

 <%@ WebHandler Language="C#" class="Hello" %> using System.Web; class Hello : IHttpHandler {    public void ProcessRequest(HttpContext ctx)    {         ctx.Response.ContentType="text/xml";         ctx.Response.Write("<Greeting>");         ctx.Response.Write("Hello World");         ctx.Response.Write("</Greeting>");    }    public bool IsReusable { get { return true; }} } 

You can then place the file in a virtual directory, navigate to it using Internet Explorer, and see the expected Hello World greeting. When you use an ashx file to create a Web service, you are using the ASP.NET HTTP pipeline at a lower level than when you use an asmx file. Instead of using the asmx handler that understands the WebMethod attribute and knows how to funnel an HTTP request to a method of a class, you are responding to the HTTP request directly by implementing the IHtpHandler interface.

HTTP Modules

HttpModules are filters that can examine and modify the contents of a request, but that do not consume the request. They are the successor to ISAPI filters. Standard HttpModules are used to implement security and session management. If you go back to the machine.config file and search for the HttpModules subelement, you will find the following entries:

 <httpModules> <add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/> <add name="Session" type="System.Web.SessionState.SessionStateModule"/> <add name="WindowsAuthentication"    type="System.Web.Security.WindowsAuthenticationModule"/> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/> <add name="PassportAuthentication"   type="System.Web.Security.PassportAuthenticationModule"/> <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/> <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/> </httpModules> 

Notice that HTTP modules handle output caching, session state, the three forms of authentication supported by ASP.NET (Windows, Forms, and Passport), and authorization based on URL or files.

Note

Output caching is a performance optimization used by ASP.NET Web Forms that caches rendered HTML. If the same page is requested again with the same parameters, the ASP.NET runtime can simply return the prerendered HTML.


You can also create your own modules by creating a class that implements the System.Web.IHttpModule interface. The IHttpModule interface contains the following methods:

 interface IHttpModule {         void Init(HttpApplication app);         void Dispose(); } 

The HttpApplication, which is passed to the Init method, defines a number of events. You define event handlers in your HttpModule to insert your own logic anywhere in the HTTP pipeline. Table 10-1 lists the HttpApplication events that you can respond to in an HttpModule.

Table 10-1. HttpApplication events

Event

When Called

BeginRequest

Before request processing starts

EndRequest

After request processing ends

AuthenticateClient

To authenticate client

AuthorizeClient

To check if the client has access rights to the requested resource

AcquireRequestState

To load session state

ReleaseRequestState

To store session state

ResolveRequestCache

To get a response from the cache

UpdateRequestCache

To update the response cache

PreRequestHandlerExecute

Before the request is sent to the handler

PostRequestHandlerExecute

After the request is sent to the handler

PreSendRequestHeaders

Before buffered response headers are sent

PreSendRequestContent

Before buffered response body is sent

In order to create a custom IHttpModule, you need to define event handlers for the events that you would like to respond to and then add these handlers to the events exposed by the HttpApplication. You then add an HTTPModule entry to the web.config file in the virtual directory of the applications that you would like to use the module. For instance, the following HttpModule calculates the processing time for each request and appends it as a header to the response. The module does this by calculating the elapsed time between the BeginRequest and EndRequest events.

 1.  using System; 2.  using System.Web; 3.  namespace TestModule 4.  { 5.      public class ResponseTimeModule : IHttpModule 6.      { 7.        DateTime mStart; 8.        public void Init(HttpApplication app) 9.        { 10.         app.BeginRequest += new 11.           EventHandler(OnBeginRequest); 12.         app.EndRequest += new 13.           EventHandler(OnEndRequest); 14.       } 15.       public void Dispose() { } 16.       public void OnBeginRequest(object o, 17.         EventArgs args) 18.       { 19.         mStart=DateTime.Now; 20.       } 21.       public void OnEndRequest(object o, 22.         EventArgs args) 23.       { 24.         TimeSpan elapsed=DateTime.Now-mStart; 25.         HttpApplication app= 26.             (HttpApplication) o; 27.         HttpContext ctx=app.Context; 28.         ctx.Response.AppendHeader(29.             "ResponseTime", 30.             elapsed.ToString()); 31.       } 32.     } 33.  } 

In the Init method on lines 8 through 14, I add handlers for the BeginRequest and EndRequest events. The event handler for the BeginRequest event is shown on lines 16 through 20. Notice that all I do is to cache the start time in a member variable of the HttpModule class. The event handler for the EndRequest event is shown on lines 21 through 31. I calculate the elapsed time between the current time and the time that was cached when the BeginRequest event handler was called on line 24. I then cast the first parameter to an HttpApplication. Remember that the first parameter to an event handler should be the source of the event, which, in this case, is the HttpApplication object. I get the HttpContext object associated with this request on line 27, and, on lines 28 through 30, I use the HttpContext object to write the response time to a custom header. If you want to abort further processing of a request in your HttpModule , simply call CompleteRequest on the HttpApplication object.

I'll compile this class into an assembly called TestModule. To make an HTTP application use this HttpModule I only need to add the following entry to the web.config file of the HTTP application:

 <httpModules>     <add name="ResponseTime"       type="TestModule.ResponseTimeModule,TestModule"/> </httpModules> 

Team-Fly    
Top
 


. Net and COM Interoperability Handbook
The .NET and COM Interoperability Handbook (Integrated .Net)
ISBN: 013046130X
EAN: 2147483647
Year: 2002
Pages: 119
Authors: Alan Gordon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net