Two More Handler Classes


At the beginning of this chapter, we noted that not all our handlers need to inherit and implement the IHttpHandler interface. We have two other options:

  • Inheriting from IHttpAsyncHandler, which lets you create an asynchronous service

  • Inheriting from IHttpHandlerFactory, which lets you create a factory class that decides, given various pieces of information, what type of handler will deal with a particular request and instantiates one accordingly

We’ll briefly look at these next.

IHttpAsyncHandler

HTTP is a synchronous protocol, so you might not associate it with asynchronous behavior in the same way you would, say, Simple Mail Transfer Protocol (SMTP). Nevertheless, the handler API provides for handlers with asynchronous responses to their requests. If you’ve included asynchronous calls in your programs before, you’ll be happy to know that you use the same programming model to implement those calls against the handler.

In our case, that means a call to the handler is made and the request is processed asynchronously, waiting for a callback to be made signaling that the process is at an end and the response can be written back to the client. For example, a handler service adjudicating a game of battleships would respond asynchronously to each client in turn, waiting for one to make a move before it responded to the previous move from the other.

Your asynchronous handler class will inherit four methods from IHttpAsyncHandler:

  • BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) This method starts the processing of the request. It takes as arguments the HttpContext object for the request, the method to be called back when the processing is complete, and any extra data needed to complete the processing. It returns an IAsyncResult object containing the current status of the process.

  • EndProcessRequest(IAsyncResult result) This method performs any cleanup required after the request has been processed. It takes as an argument the current status of the processing.

  • IsReusable and ProcessRequest(HttpContext context) These methods are inherited from IHttpHandler and work in the same way. Note that ProcessRequest must be present but doesn’t need to be called.

We’ll cover asynchronous Web service programming at the Web method level in Chapter 7. You’ll find a simple example of an asynchronous handler in the .NET Framework documentation at ms-help://MS.NETFrameworkSDK/cpguidenf/html/cpconhttphandlerregistration.htm. You’ll also find a full introduction to asynchronous programming in the SDK at ms-help://MS.NETFrameworkSDK/ cpguidenf/html/cpovrasynchronousprogrammingoverview.htm.

IHttpHandlerFactory

As the name IHttpHandlerFactory suggests, a class that implements this interface is not a handler in itself but offers an alternative (and arguably more elegant) way to deal with requests into a Web service. Thus far, we’ve developed a handler that discerns how the service is being requested and calls a method to give an appropriate response. A handler factory class discerns how the service is being requested and creates a handler to give the appropriate response—a similar tactic but with different implications. In the former situation, we’re reusing large handler objects designed to deal with all eventualities. In the latter, we’re reusing much smaller handlers built for a specific request—HTTP-GET, HTTP-POST, synchronous, asynchronous, and so on. When you scale up the number of requests and performance becomes an issue, the HandlerFactory might be the way to go.

IHttpHandlerFactory contains two methods:

  • GetHandler(HttpContext context, string requestType, string url, string pathTranslated), which returns a handler object to the pipeline that will process the given request. It takes as parameters the HttpContext object for the current request, the HTTP request type (GET, POST, and so on), and the location of the requested file given as a URL and local file path.

  • ReleaseHandler(IHttpHandler handler), which releases a handler no longer being used back to the factory class so it can be reused when required.

Like ProcessRequest in our handler classes thus far, GetHandler might well need only a couple of if statements to figure out what it needs to do, as in this example:

class HandlerFactory : IHttpHandlerFactory {          public IHttpHandler GetHandler(HttpContext context,          string requestType, String url, String pathTranslated)     {         IHttpHandler handlerToReturn;         switch (requestType.ToLower())         {             case "get":                 handlerToReturn = new HttpGetHandler();                 break;             case "post":                 switch (context.Request.ContentType)                 {                     case "text/plain":                     case "application/x-www-form-urlencoded":                         handlerToReturn = new HttpPostHandler();                         break;                     case "text/xml":                         handlerToReturn = new HttpSoapHandler();                         break;                     default:                         throw new Exception                             ("Plain text, form or SOAP POST requests "                                 + "only please.");                 }                 break;             default:                 throw new Exception("GET or POST requests "                     + "only please");         }         return handlerToReturn;     }      }

The logic here works in exactly the same way as in previous examples; it’s left to you to implement each of the handler classes (which inherit from IHttpHandler or IHttpAsyncHandler, of course). Likewise, you can register an association between the factory class and a file extension in your web.config in the same way you did with “single” handler classes.




Programming Microsoft. NET XML Web Services
Programming MicrosoftВ® .NET XML Web Services (Pro-Developer)
ISBN: 0735619123
EAN: 2147483647
Year: 2005
Pages: 172

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