So far, most attention has focused on the Page class. The Page class is responsible primarily for managing the UI aspects of an application. Because UI processing is very involved (and much of it is boilerplate-type code), the Page class has a great deal of functionality built into it. The Page class can solve the majority of user interface needs that require UI processing.
Although you haven't come across Web services yet, the WebService
class implements the details required to interpret HTTP requests as
method calls. Clients call Web services by packaging method calls in an
XML format formalized as SOAP.
Note:
Formerly, the acronym
SOAP stood for Simple Object Access Protocol, but as of SOAP 1.2 the
spelled-out version has been dropped to avoid confusion—SOAP isn't about
objects and it isn't necessarily simple, at least to implement.
Clients call Web services in the same way they make HTTP requests
for Web pages—through the HTTP GET and POST requests. When the request
reaches the server, it becomes the server's job to unpack the
parameters, place them on a real or virtual call stack, and finally
invoke the correct method.
Most of the work required to make a method call through HTTP is well
understood and consistent and can be pushed down into the WebService class.
The endpoint for all HTTP requests destined for ASP.NET is a class implementing IHttpHandler. IHttpHandler
is a simple interface, including a mere two methods. However, any class
implementing that interface qualifies to participate in the HTTP
pipeline as an HTTP handler.
HTTP handlers are simply classes that implement IHttpHandler (just as HTTP modules are classes implementing IHttpModule). Handlers are listed inside web.config. As with the HTTP modules, ASP.NET comes out of the box with several HTTP
handlers (for implementing features such as tracing and preventing
access to sensitive files on the site). ASP.NET comes with these HTTP
handlers already registered in the master web.config configuration file,
which resides alongside machine.config in the main configuration
directory.
So far, ASPX, ASAX, and ASCX
files have seemed to work magically in ASP.NET. For example, you saw
earlier that simply surfing to an ASPX file causes ASP.NET to compile
the file just in time and to synthesize a class based on System.Web.UI.Page. The reason the ASPX files work that way is that ASP.NET includes handlers for that functionality.
ASP.NET HTTP handlers are
specified in web.config in much the same way as HTTP modules. The format
of the handler elements includes four items. First, they include a file
name and/or extension to which the handler applies. This is done
through the add
attribute. Remember, all HTTP requests come to the server as resource
requests—the HTTP protocol is built around the idea that requests
contain resource names. The second part of the handler specification, verb, is a list of verbs to which this handler applies. These verbs
correspond to the HTTP specification. For example, you might want a
handler to apply only to GET and not to POST requests. Or you might wish
to have a handler apply to all requests. The third element, type, is the name of the .NET type assigned to handle the request. Finally, the last attribute, validate, specifies whether ASP.NET should load the class at startup immediately or wait until a matching request is received.
Example 1 includes a smattering of the HTTP handlers already installed as part of the ASP.NET master web.config file.
Example 1. Excerpt from the master web.config file
<httpHandlers> <add path="trace.axd" verb="*" type="System.Web.Handlers.TraceHandler" validate="True" /> <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True" /> <add verb="*" path="*_AppService.axd" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False" /> <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers. ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False"/> <add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" /> <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" /> <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" /> <add path="*.asmx" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False" /> <add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" /> <add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" /> <add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> <add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> <add path="*.master" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> <add path="*.skin" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> <add path="*.browser" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> <add path="*.sitemap" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> <add path="*.dll.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="True" /> <!-More handlers follow... --> </httpHandlers>
|
The following sections look at a couple of specific handlers—the Trace handler and the Forbidden handler—to show how having a separate request handling facility (that is, one that is not tied specifically to UI or to Web services) can be useful.