ASP. NET Request Processing Process:
When a * .aspxfile is requested, the request will be intercepted by the inetinfo.exe process. After determining the file suffix (aspx), it will forward the request to aspnet_isapi.dll, aspnet_isapi.dll sends the request to aspnet_wp.exein the HTTP pipeline. The request is processed through httpruntime in the aspnet_wp.exe process. After the request is processed, the result is returned to the client.
Inetinfo.exe process:Is the WWW Service Process, IIS service and aspnet_isapi.dll are stored in this process.
Aspnet_isapi.dll: A Win32 component used to process the. aspx file. The iisserver can only identify the .html file. When the IIS server finds that the requested file is a. aspx file, the IIS server submits it to aspnet_isapi.dll for processing.
Aspnet_wp.exe process:The ASP. NET Framework process provides a managed environment for. Net Running. the. net clr (Common Language Runtime) is stored in this process.
ASP. NET Framework processes an HTTP request:
Httprequest --> inetinfo.exe --> response --> aspnet_wp.exe --> httpruntime --> httpapplication factory --> httpapplication --> httpmodule --> httphandler factory --> httphandler. processrequest ()
ASP. the net request processing process is based on the pipeline model, which consists of multiple httpmodules and httphandler, Asp.. Net passes the HTTP request to each httpmodule in the pipeline in sequence, and is finally processed by httphandler. After the processing is completed, it passes through the HTTP module in the pipeline again and returns the result to the client. We can intervene in the request processing process in each httpmodule.
Note: During HTTP request processing, only one httphandler can be called, but multiple httpmodules can be called.
When the request arrives at HttpModule, the system has not actually processed the request, but we can add some other information before the request is passed to the processing center (HttpHandler, or intercept the request and do some additional work, or terminate the request. After HttpHandler finishes processing the request, we can re-process the request processing result in the corresponding HttpModule and return it to the client.
Httpmodule
The HTTP module is a class that implements the System. Web. IhttpModule interface.
IHttpModule interface declaration:
Public interface IHttpModule
{
Void Init (HttpApplication context );
Void Dispose ();
}
Init method: This method is automatically called during system initialization. This method allows the HTTP module to register its own event handler with the event in the httpapplication object.
Dispose method: This method gives the HTTP module the opportunity to clean up objects before they are collected by garbage collection. This method generally does not require coding.
The HTTP module registers the following events with the System. Web. HttpApplication object:
AcquirerequeststateThis event is triggered when ASP. NET is ready to receive the dialog status of the current HTTP request.
AuthenticaterequestThis event is triggered when ASP. NET is running to verify the user identity.
AuthorizerequestThis event is triggered when ASP. NET is ready to authorize users to access resources.
BeginrequestThis event is triggered when ASP. NET receives a new HTTP request.
DisposedThis event is triggered when ASP. NET completes HTTP request processing.
EndrequestThis event is triggered before the response content is sent to the client.
ErrorThis event is triggered when an unhandled exception occurs during HTTP request processing.
PostRequestHandlerExecuteThis event is triggered when the HTTP processing program ends.
PreRequestHandlerExecuteThis event is triggered before ASP. NET starts executing the HTTP request processing program. After this event, ASP. NET forwards the request to an appropriate HTTP handler.
PreSendRequestContentThis event is triggered before ASP. NET sends the response content to the client. This event allows us to change the response content before the content arrives at the client. We can use this event to add content for all pages to the page output. For example, general menu, header information, or foot information.
PreSendRequestHeadersThis event is triggered before ASP. NET sends the HTTP response header information to the client. Before the header information arrives at the client, this event allows us to change its content. We can use this event to add cookies and custom data to the header information.
ReleaseRequestStateThis event is triggered when ASP. NET ends the execution of the searched request handler.
ResolveRequestCacheThis event is triggered to determine whether the request can end with the content returned from the output buffer. This depends on how to set the Web application output buffer.
UpdateRequestCacheThis event is triggered when ASP. NET processes the current HTTP request and the output content is ready to be added to the output buffer. This depends on how the Web application's output buffer is set.
The above events may seem dizzy, but it doesn't matter. Let's take a look at them step by step.
HttpModule Lifecycle
The event trigger sequence is as follows:
The event between BeginRequest and PreRequestHandlerExecute is triggered before the server executes HttpHandler processing.
Events between PostRequestHandlerExecute and PreSendRequestContent are triggered after the server executes Handler processing.
Next, let's take a look at how to use HttpModule to implement our daily applications:
HttpModule inserts itself into the ASP. NET Request Processing pipeline by registering in some events. When these events occur, ASP. NET calls the corresponding HTTP module so that the module can process requests.
1. Add some remarks or descriptive text to each page dynamically:
In some websites, an advertisement is displayed on each page or each page is annotated (<! -->) Add the copyright information of the website. If you want to write such JS Code on each page, writing and maintaining such JS Code for a large website is a tedious task.
With HttpModule, we can easily solve this problem. HttpModule is the only way for the client to send a request to the client to receive the server response. After the server completes processing the request and sends the response text to the client, we can add the comment text to the page text. In this way, each page request will be appended with this text comment.
In which event should this code be implemented? Any event between PostRequestHandlerExecute and PreSendRequestContent can be used, but I prefer to write code in the EndRequest event.
Step 1: Create a class library ClassLibrary831.
Step 2: compile a class to implement the IHttpModule Interface
Class TestModule: IHttpModule
{
Public void Dispose ()
{
}
Public void Init (HttpApplication context)
{
}
}
Step 3: register the EndRequest event in the Init event and implement the event processing method.
Class TestModule: IHttpModule
{
Public void dispose (){}
Public void Init (httpapplication context)
{
Context. EndRequest + = new EventHandler (context_EndRequest );
}
Void context_EndRequest (object sender, EventArgs e)
{
Httpapplication HA = (httpapplication) sender;
Ha. response. Write ("<! -- This is the text generated dynamically on every page. -- Grayworm --> ");
}
}
Step 4: register the HttpModule module in Web. Conofig
<HttpModules>
<Add name = "TestModule" type = "ClassLibrary831.TestModule, ClassLibrary831"> </Add>
</HttpModules>
Name: Module name, which is generally a class name
Type: it consists of two parts: the first half is the full name composed of the namespace and class name, and the second half is the Assembly name. If the class is directly placed in the App_Code folder, the program name is App_Code.
In this way, after you add a reference to the class library on the Web site and run each page, you will find that "<! -- This is the text generated dynamically on every page. -- Grayworm -->. You can also add JS code in the same method.
2. Identity check
When you log on successfully, you generally need to store the user name in the Session and check whether there is a user name in the Session in the Page_Load event of each other page, if it does not exist, it indicates that the user has not logged on and will not allow the user to access the content.
In a relatively large program, this method is too clumsy, because you have to add the detection Session code in almost every page, making it difficult to develop and maintain. Next, let's take a look at how to use HttpModule to reduce our workload.
Because we need to use the Session content here, we can only write code in the AcquireRequestState and PreRequestHandlerExecute events, because only these two events in HttpModule can access the Session. Here we select the PreRequestHandlerExecute event to write code.
Step 1: Create a class library ClassLibrary831.
Step 2: compile a class to implement the IHttpModule Interface
Class TestModule: IHttpModule
{
Public void Dispose ()
{
}
Public void Init (HttpApplication context)
{
}
}
Step 3: register the prerequesthandlerexecute event in the init event and implement the event processing method.
Class AuthenticModule: IHttpModule
{
Public void dispose (){}
Public void Init (httpapplication context)
{
Context. PreRequestHandlerExecute + = new EventHandler (context_PreRequestHandlerExecute );
}
Void context_PreRequestHandlerExecute (object sender, EventArgs e)
{
Httpapplication HA = (httpapplication) sender;
String Path = ha. Context. Request. url. tostring ();
Int n = path. ToLower (). IndexOf ("Login. aspx ");
If (n =-1) // whether it is a logon page. if it is not a logon page, enter {}
{
If (ha. Context. Session ["user"] = null) // whether the Session has a user name. if it is null, go to the logon page.
{
Ha. Context. Response. Redirect ("Login. aspx? Source = "+ path );
}
}
}
}
Step 4: Add the following code to the "Log on" button on the Login. aspx page
Protected void button#click (object sender, EventArgs e)
{
If (true) // determine whether the user name and password are correct
{
If (Request. QueryString ["source"]! = Null)
{
String S = request. querystring ["Source"]. tolower (). tostring (); // retrieve the page from which it is converted
Session ["user"] = txtuid. text;
Response. Redirect (s); // go to the desired page
}
Else
{
Response. Redirect ("main. aspx"); // default switch to main. aspx
}
}
}
Step 5: register the HttpModule module in Web. Conofig
<HttpModules>
<Add name = "TestModule" type = "ClassLibrary831.TestModule, ClassLibrary831"> </add>
</HttpModules>
3. multi-module operations
If multiple httpmodules are defined, the order in which custom httpmodules are introduced in the web. config file determines the order in which multiple custom httpmodules take over an HTTP request.
HttpHandler
HttpHandler is the processing center of HTTP requests. It truly compiles and executes the server pages of client requests, and attaches the processed information to the HTTP request information stream and returns it to HttpModule again.
HttpHandler is different from HttpModule. Once you define your own HttpHandler class, its relationship to the system's HttpHandler will be "overwritten.
IHttpHandler interface declaration
Public interface IHttpHandler
{
Bool IsReusable {get ;}
Public void ProcessRequest (HttpContext context); // request processing function
}
Example: Write the image on the hard disk as a stream on the page
Class TestHandler: IHttpHandler
{
Public void ProcessRequest (HttpContext context)
{
FileStream fs = new FileStream (context. Server. MapPath ("worm.jpg"), FileMode. Open );
Byte [] B = new byte [fs. Length];
Fs. Read (B, 0, (int) fs. Length );
Fs. Close ();
Context. Response. OutputStream. Write (B, 0, B. Length );
}
Public bool IsReusable
{
Get
{
Return true;
}
}
}
Web. config configuration file
<HttpHandlers>
<Add verb = "*" path = "*" type = "ClassLibrary831.TestHandler, ClassLibrary831"> </add>
</HttpHandlers>
Verb attribute: Specifies the HTTP action supported by the handler. *-All HTTP actions are supported. "Get"-Get operations are supported. "Post"-post operations are supported. "Get and post"-two operations are supported.
Path attribute: Specifies the path and file name of the handler to be called (which can contain wildcards ). "*", "*. Aspx", "showimage. aspx", "test1.aspx, test2.aspx"
Type attribute: Specify the actual type of the handler or handler factory by combining the namespace, class name, and assembly name. When ASP. NET is running, search for the DLL in the bin directory and then GAC.
The result of running this program is that any page on the website displays the worm.jpg image. How can I have only one page (default21.aspx) execute the ProcessRequest method in HttpHandler? The simplest way is to set the path configuration information to default21.aspx in the Web. Config file.
Based on this example, you can consider how to compile the "Verification Code.
IHttpHandler Factory
IHttpHandlerFactory is used to manage IHttpHandler. For the role of the factory, see http://hi.baidu.com/grayworm/blog/item/4a832160f8c9de46eaf8f8c1.html"
IHttpHandlerFactory interface declaration:
Public interface IHttpHandlerFactory
{
IHttpHandler GetHandler (HttpContext context, string requestType, string url, string pathTranslated );
Void releasehandler (ihttphandler handler );
}
Gethandler returns an instance of the class implementing the ihttphandler interface. releasehandler allows the factory to reuse existing handler instances.
Example: two calls to different httphandlerfactory are implemented using ihttphandlerfactory.
There are two httphandler: The httphandler that displays the image on the page and the handler that generates the verification code
// Handler that displays the image on the page
Class testhandler: ihttphandler
{
Public void processrequest (httpcontext context)
{
FileStream fs = new FileStream (context. Server. MapPath ("worm.jpg"), FileMode. Open );
Byte [] B = new byte [fs. Length];
Fs. Read (B, 0, (int) fs. Length );
Fs. Close ();
Context. Response. OutputStream. Write (B, 0, B. Length );
}
Public bool IsReusable
{
Get
{
Return true;
}
}
}
// Handler that generates the verification code
Class CodeHandler: IHttpHandler
{
Public bool isreusable
{
Get
{
Return true;
}
}
Public void processrequest (httpcontext context)
{
Image B = new Bitmap (50, 20 );
Graphics g = Graphics. FromImage (B );
SolidBrush sb = new SolidBrush (Color. White );
Font f = new Font ("", 12 );
String str = "";
Random r = new Random ();
For (int I = 0; I <4; I ++)
{
Str + = r. Next (10 );
}
G. DrawString (str, f, sb, 0, 0 );
B. Save (context. Response. OutputStream, System. Drawing. Imaging. ImageFormat. Jpeg );
}
}
IHttpHandler Factory
Class TestHandlerFactory: IHttpHandlerFactory
{
Public IHttpHandler GetHandler (HttpContext context, string requestType, string url, string pathTranslated)
{
String fname = url. Substring (url. IndexOf ('/') + 1 );
While (fname. IndexOf ('/')! =-1)
Fname = fname. Substring (fname. IndexOf ('/') + 1 );
String cname = fname. Substring (0, fname. IndexOf ('.'));
String className = "";
ClassName = "ClassLibrary831.CodeHandler ";
Object h = null;
Try
{
// H = new TestHandler ();
H = Activator. CreateInstance (Type. GetType (className ));
}
Catch (Exception e)
{
Throw new HttpException ("the factory cannot be of the type" + cname + "to create an instance. ", E );
}
Return (IHttpHandler) h;
}
Public void ReleaseHandler (IHttpHandler handler)
{
}
} (CHE Yanlu)
Configuration File
<HttpHandlers>
<Add verb = "*" path = "default21.aspx, default22.aspx" type = "ClassLibrary831.TestHandlerFactory, ClassLibrary831"> </add>
</HttpHandlers>
In this way, testhandlerfactory will execute different httphandler handlers based on different pages of the request.
HttpHandler uses session
If you want to use the session in the processing program, you must implement the httphandler irequiressessionstate interface. The irequiressessionstate interface is a null interface, which has no abstract method and is just a flag. This is not verified by examples.