Mark Wilson I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
Govind works for Cap Gemini Ernst and Young at Bellevue, WA.
This article will explain to the reader about how to write
handlers, modules and provide some insight into how ASP.NET works.
This architecture ships with the .NET beta sdk and sits on top of
IIS.
The new ASP.Net architecture is highly extensible and allows
third parties to create new functionality. It removes the barrier
to writing the request handlers/interceptors by removing the
dependence on ISAPI based architecture. You don't have to delve out
of the ASP.NET or deal with ECB (Extension control Block - a
structure used to pass data and pointer to callback functions
inside the IIS runtime) kind of ISAPI structures anymore. You will
come to appreciate the hard work of the Microsoft developers for
such awesome product to make our life so much easier.
a. Module - a sample module implementation
- global.asax - handling events in the global.asax
- logmodule.cs - the module
b. Handler
- handler.cs - sample implmentation of handler
c. config.web
- this file has commented out sections, uncomment them as you go.
Instructions
Create a directory to act as your application root. Mark it as your vroot via the IIS service manager by creating virtual directory pointing to the same.
Create another directory called as "bin" below the application root. That is where our binaries will be going when we compile the directory.
Create the samples in the application root - see next two items 4 and 5
Compiling the module
csc /target:library /out:bin/logHost.dll logModule.cs /r:System.Web.dll /r:System.dll /debug+
Compiling the module
csc /target:library /out:bin/handler.dll handler.cs /r:System.Web.dll /r:System.dll /debug+
ASP.Net has moved away from WAM-IIS marriage to a much cleaner
architecture (see Figure 1). ASP.Net and erstwhile ASP applications
can work side by side. In case of ASP.Net a new ISAPI dll
XSPISAPI.dll happens to be the broker of requests for ASP.Net
specific URLs (.aspx.ashx.asmx etc). The difference is that
now the requests are handled by request handlers hosted inside
xspwp.exe, a worker process. The communication between the
XSPISAPI.dll and XSPWP.exe is through an anonymous named pipe.
Before and after the request is handled the runtime provides us the
events, which we can trap to enhance the functionality of the
system through modules.
Handlers are akin to ISAPI extension
dll whereas modules are same as ISAPI filters in the old
infrastructure of ASP.
ASP.NET object model is based on
System.Web.HttpContext. HttpContext is a superset of the classic
ASP object model. One HttpContext object exists for each
request being serviced, the correct HttpContext object is passed
explicitly to HTTP handlers. The current HttpContext object is
exposed via the static property HttpContext.Current.
What happens when a request for .aspx resource arrives ?
Most of the following information is based on the looking at
stack trace when a fault occurs while processing a request and from
reading Scott G's informative mails in the aspng list. ASP.NET 's
new extension dll xspisapi.dll listens for the request on the http
port. It constructs the ecb and sends it across the pipe to the
xspwp (xsp worker process) , which looks for the correct
pagefactory and passes the request. In between the time Actual
handler is invoked, modules/global.asax are allowed to intercept
various events which the runtime raises while processing the
request. A HttpContext object containing all the information about
the request is also created and flown along. If this is the first
request for the .aspx resource, a class derived from the UI.Page is
created. It is then compiled and cached for the next requests and
the result sent back. Along the way some more events are raised by
the runtime for the modules to intercept. If the .aspx pages
contains the server controls etc, this page is created,compiled ,
saved to the disk and rendered and all the events
(clicked,page_load etc) are fired.
Quick and Dirty Guide to Config.web
Config.web is the xml based configuration for IIS application
which is more cleaner and maintainable than using IIS metabase for
the same. This file if present in an application( remember the good
old definition of app in IIS ? - A virtual directory ) The
config.web as its name suggests provides configuration mechanisms
for a web application. It is not required, in that case the
default config.web information is used. But you can provide your
own config.web for your application which can contain tonnes of
settings for you application.
It is semi-xml kind of file
e.g.,
<configuration>
<section Attributes>
<MoreSettings>
</section>
</configuration>
It is also actively monitored for changes. So any change in it
will be automatically processed and implemented without requiring
IIS restarts. It allows to add new handlers or replace existing
ones. It allows to register custom interception modules. It
contains the configuration information about session state and
where it should be maintained. It also specifies security settings
for an application and user defined element types.
It is inheritable across the hierarchy of the vroot
application.
Quick and Dirty guide to Assembly, module, Appdomain
Assemblies are the atom of deployment in the CLR
, they are used to package and distribute executable code.
An assembly consists of one or more modules. The assembly
manifest is the catalog of modules and external assembly
references. Each module (and assembly) begins with a manifest
describing its dependencies, which contains a list of external
assembly references. Appdomains are new logical processes, which
are the main unit of execution. Please refer to the .NET SDK
documentation to get more details.
Understanding the marriage of CLR and the ASP.NET
CLR the common language runtime provides the framework for new
ASP.NET to provide compiled intralanguage operation, base class
framework ensuring same fidelity treatment for all the languages.
It also provides the process management, memory management for the
ASP.NET .
Debugging Module/Handler
Use C:\Program
Files\Microsoft.Net\FrameworkSDK\GuiDebug\dbgUrt.exe to attach to
xspwp.exe and enumerate the different domains you want to attach
to. Load the source code for the module/handler, place a break
point and browse to the offending site. You can step through the
code easily. Remember to create the debug version of the dll
by providing extra attribute while compiling(/debug+).
Following table provides the events which can be fired during
the processing of the request. Interception of events allows to
extend the functionality of the ASP.NET. You can write your own
caching, authentication applications.
Application_BeginRequest
Application_AuthenticateRequest
Application_AuthorizeRequest
Application_ResolveRequestCache
Application_AquireRequestState
Application_PreRequestHandlerExecute
Application_PostRequestHandlerExecute
Application_ReleaseRequestState
Application_UpdateRequestCache
Application_EndRequest
Application_PreSendRequestHeaders
Application_PreSendRequestContent
Application_Error
Interception can occur in 2 places :
-Global.asax
-Module
Following global.asax code demonstrates the handling of
events.
<script language="VB" runat=server>
Sub Application_Start()
' Run code when application
starts
End Sub
Sub Application_BeginRequest()
Response.Write("We are
starting the processing of this request! From global.asax")
End Sub
Sub Application_End()
' Run code when application
starts
End Sub
</script>
Testing the interception via global.asax
After you create the global.asax as mentioned in your
application vroot and visit the site. You should see the message as
below in Figure 2
Figure 2
The global.asax piece of code is easier to add and maintain but
not suitable for a commercial component you might want to sell.
A module is class which implements specific interface and hosted
in special directory and wired up to be notified by the runtime
when events it is interested in happen.
Writing a new module is pretty simple. It involves 3 steps:
1. To implement the module one has to implement the interface
IHttpModule
2. Compile and deploy .Net Library DLL within "bin" dir under
app vroot
3. Register Module in config.web:
<configuration>
<httpmodules>
<add
type="classname, assembly "/>
</httpmodules>
</configuration>
Modules implement an Interface System.Web.IHttpModule
public interface IHTTPModule
{
public String ModuleName { get; }
public void Init(HTTPApplication application);
public void Dispose();
}
Trapping the event you are interested in
Let us create a file called as logModule.cs having the following
code.
using System;
using System.Web;
public class logModule :IHttpModule { //Start of class
public void Init( HttpApplication hc)
{
// trap the event you are interested in
hc.EndRequest += (new
EventHandler(this.Application_EndRequest));
}
We tell the executing application that we can handle its
EndRequest event by providing an implementation for the same as
below:
ct.Response.Write("This line is being written from the module's
interception at the end of the
request");
}
public string ModuleName {
get {
return "LogModule";
}
}
} // end of class
Compiling the program
Create a directory bin under your application root. That is
where we will be writing our output file. The bin directory
contents are directly picked up by the ASP.Net processing engine
based on the config.web contents.
Create following config.web to enable ASP.Net to pick up our
interceptor.
<configuration>
<httpmodules>
<add type="logModule, logHost"/>
</httpmodules>
</configuration>
Testing the module
Create a virtual directory pointing to the application root
(where your source code resides) using the IIS service manager. Put
the config.web into this directory. Remember you had created a bin
directory under this application vroot.
The following figure (figure 3)demonstrates the output.
Figure 3
Handling the Custom URL request
Now that we have down intercepting the request handling, we will
move on to writing Handlers. They enable processing of
URL extensions within an app and analogous to ISAPI Extensions of
ASP era. But the good thing is you can write these handlers in CLR
aware language and have the support of ASP.NET infrastructure. The
sample handlers installed by default are the ones for .aspx, .asmx.
Handlers are implemented as a class implementing the
System.Web.IhttpHandler interface.
public interface IHTTPHandler
{
// processes the request
public void ProcessRequest(HTTPContext context);
// indicates the poolability of the instance of the handler
Add the following section to the config.web, we are telling the
ASP.NET that in this application we have handler whose class name
is Myhandler and it hosted inside handler assembly and it listens
for myfile.ext requests.
Well we are going to register our extension with the
XSPISAPI.dll via the IIS service manager.
Testing our handler
It is pretty easy. Start up your browser and visit a url named
as myfile.ext in your application vrrot. In my case it was
http://localhost/module/myfile.ext . Following was the result.
Remember the second line is coming from our module which we had
written handler.
Intercepting the request is pretty straight forward with the new
infrastructure. Only precaution to be taken is not to spend more
time in the module. Examples of custom modules could include custom
authentication, caching modules, custom exception handling modules
or anything else you can fancy. Handlers allow you to serve up the
content for group of URLs or URLs with specific extensions. If you
looked at the default config.web file, you would have found how web
services, remoting extra are enabled on the IIS.