In my previous article, I mentioned the simple use of httpmodule and httphandle. We can use them to add our own event handlers during page requests. So what does the background do when An ASPX page request is sent? Of course, Asp.net has done a lot of things and the process is complicated. This article mainly analyzes the general process. The overall process is as follows:
When a page is requested, it is first intercepted by the wwwservice (inetinfo.exe process). This process first determines the page suffix and then determines which extension program to call based on the configuration in IIS. For example, the ASPX page calls C: /Windows/IIS (when we debug the IIS website, We append vs2005 to this process ).
The w3wp.exe process will call the. NET class library for specific processing:
Isapiruntime --> httpruntime --> httpapplicationfactory --> httpapplication --> httpmodule -- httphandlerfactory --> httphandler, which is the main analysis area of this article.
The following is a list of the main processes. If you want to study it, you can use reflector to view it.
I. isapiruntime
Bool useoop = iwrtype = 1;
WR = isapiworkerrequest. createworkerrequest (ECB, useoop );
Wr. initialize ();
String apppathtranslated = Wr. getapppathtranslated ();
String appdomainapppathinternal = httpruntime. appdomainapppathinternal;
If (appdomainapppathinternal = NULL) | stringutil. inclusignorecase (apppathtranslated, appdomainapppathinternal ))
{
Httpruntime. processrequestnodemand (WR );
Return 0;
}
Httpruntime. shutdownappdomain (applicationshutdownreason. physicalapplicationpathchanged, Sr. getstring ("hosting_phys_path_changed", new object [] {appdomainapppathinternal, apppathtranslated }));
Return 1;
Its main function is to call some unmanaged code to generate an httpworkerrequest object, which contains all the information of the current request and then passes it to httpruntime, the httpworkerrequest object generated here can be called directly on our page to obtain the original request information:
Iserviceprovider provider = (iserviceprovider) httpcontext. Current;
Httpworkerrequest wR = (httpworkerrequest) provider. getservice (typeof (httpworkerrequest ));
Ii. httpruntime
The most important is the private void processrequestinternal (httpworkerrequest wr) method: context = new httpcontext (WR, false );
Ihttphandler applicationinstance = httpapplicationfactory. getapplicationinstance (context );
Ihttpasynchandler handler2 = (ihttpasynchandler) applicationinstance;
Context. asyncapphandler = handler2;
Handler2.beginprocessrequest (context, this. _ handlercompletioncallback, context );
1. Generate httpcontext Based on the httpworkerrequest object. httpcontext should be familiar to everyone. It contains attributes such as request and response, which are often used on pages;
2. Call httpapplicationfactory to generate ihttphandler (a default httpapplication object is generated here, And httpapplication is also an implementation of the ihttphandler Interface)
3. Call the httpapplication object to execute the request
Iii. httpapplicationfactory
As mentioned in 2.2, here we mainly generate an httpapplication object:
Internal static string getapplicationfile ()
{
Return Path. Combine (httpruntime. appdomainapppathinternal, "Global. asax ");
}
First, check whether global exists. asax file, if any, use it to generate the httpapplication object. here we can see global. the file name of asax is written to death in the Asp.net framework and cannot be modified. If this file does not exist, use the default object.
Initialize the httpapplication after it is created:
Application = (httpapplication) httpruntime. createnonpublicinstance (this. _ theapplicationtype );
Using (applicationimpersonationcontext context2 = new applicationimpersonationcontext ())
{
Application. initinternal (context, this. _ state, this. _ eventhandlermethods );
}
Iv. httpapplication
This is a complex and important object.
The first step is to perform initialization. The more important step is to initialize the httpmodule: Private void initmodules ()
{
This. _ modulecollection = runtimeconfig. getappconfig (). httpmodules. createmodules ();
This. initmodulescommon ();
} It reads the configurations of all httpmodules in Web. config.
Bind the module event handler in the hookupeventhandlersforapplicationandmodules method and then bind the event:
If (httpruntime. useintegratedpipeline)
{
This. _ stepmanager = new pipelinestepmanager (this );
}
Else
{
This. _ stepmanager = new applicationstepmanager (this );
}
This. _ stepmanager. buildsteps (this. _ resumestepswaitcallback );
The event binding execution sequence is displayed in the buildsteps method of applicationstepmanager:
App. createeventexecutionsteps (httpapplication. eventbeginrequest, steps );
App. createeventexecutionsteps (httpapplication. eventauthenticaterequest, steps );
App. createeventexecutionsteps (httpapplication. eventdefaauthauthentication, steps );
App. createeventexecutionsteps (httpapplication. eventpostauthenticaterequest, steps );
App. createeventexecutionsteps (httpapplication. eventauthorizerequest, steps );
App. createeventexecutionsteps (httpapplication. eventpostauthorizerequest, steps );
App. createeventexecutionsteps (httpapplication. eventresolverequestcache, steps );
App. createeventexecutionsteps (httpapplication. eventpostresolverequestcache, steps );
Steps. Add (New httpapplication. maphandlerexecutionstep (APP ));
App. createeventexecutionsteps (httpapplication. eventpostmaprequesthandler, steps );
App. createeventexecutionsteps (httpapplication. eventacquirerequeststate, steps );
App. createeventexecutionsteps (httpapplication. eventpostacquirerequeststate, steps );
App. createeventexecutionsteps (httpapplication. eventprerequesthandlerexecute, steps );
Steps. Add (New httpapplication. callhandlerexecutionstep (APP ));
App. createeventexecutionsteps (httpapplication. eventpostrequesthandlerexecute, steps );
App. createeventexecutionsteps (httpapplication. eventreleaserequeststate, steps );
App. createeventexecutionsteps (httpapplication. eventpostreleaserequeststate, steps );
Steps. Add (New httpapplication. callfilterexecutionstep (APP ));
App. createeventexecutionsteps (httpapplication. eventupdaterequestcache, steps );
App. createeventexecutionsteps (httpapplication. eventpostupdaterequestcache, steps );
This. _ endrequeststepindex = steps. count;
App. createeventexecutionsteps (httpapplication. eventendrequest, steps );
Steps. Add (New httpapplication. noopexecutionstep ());
Note that maphandlerexecutionstep marked in red (read all httphandler configurations) and callhandlerexecutionstep are used to process the handle program, that is, in the web. the httphandler configured in config is processed here. The execution sequence is shown in the preceding figure.
Then, call the method execution request in 2.3:
Code
Iasyncresult ihttpasynchandler. beginprocessrequest (httpcontext context, asynccallback CB, object extradata)
{
This. _ context = context;
This. _ context. applicationinstance = this;
This. _ stepmanager. initrequest ();
This. _ context. Root ();
Httpasyncresult result = new httpasyncresult (CB, extradata );
This. asyncresult = result;
If (this. _ context. traceisenabled)
{
Httpruntime. profile. startrequest (this. _ context );
}
This. resumesteps (null );
Return result;
}
In resumesteps, the event handler is executed.
V. httpmodule
The default configuration in system web. config is as follows:
Code
For basic usage, see my previous article.
6. httphandlerfactory and httphandler
The configuration methods of the two objects in Web. config are the same. The default configurations are as follows:
Code
Note that if the same suffix name is configured multiple times, the subsequent configuration will overwrite the previous one.
Here we will focus on the configuration of aspx: system. Web. UI. pagehandlerfactory
This is an httphandlerfactory object. Different httphandler objects are generated based on different pages (our own page is an ihttphandler ):
Page page = buildmanager. createinstancefromvirtualpath (virtualpath, typeof (PAGE), context, true, true) as page;
If (page = NULL)
{
Return NULL;
}
Page. templatecontrolvirtualpath = virtualpath;
Return page;
The buildproviders configuration compilation page in Web. config will be called here:
Code
In this way, we can enter our page for execution. For more information about the large execution order, see the description in section 4, which is also an httphandler.
This article is transferred from
Http://www.cnblogs.com/firstyi/archive/2008/05/08/1188545.html