請求一個頁面時首先被WWW服務截獲(inetinfo.exe程序),這個程序首先判斷頁面的字尾,然後根據IIS中的配置來決定調用哪個擴充程式,比如aspx的頁面就會調用c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll,aspnet_isapi.dll将請求發送給w3wp.exe程序(我們在調試IIS中網站時就是把VS2005附加到這個程序上的)。
接下來w3wp.exe程序就會調用.net類庫進行具體處理:
ISAPIRuntime-->HttpRuntime-->HttpApplicationFactory-->HttpApplication-->HttpModule--HttpHandlerFactory-->HttpHandler 這也是本文主要分析的地方。
下面隻是列出主要流程,如果喜歡鑽研的同學可以用Reflector去檢視
一:ISAPIRuntime

bool useOOP = iWRType == 1;

wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);

wr.Initialize();

string appPathTranslated = wr.GetAppPathTranslated();

string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;

if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
{
HttpRuntime.ProcessRequestNoDemand(wr);
return 0;
}
HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated }));

return 1;

它的主要作用是調用一些非托管代碼生成HttpWorkerRequest對象,該對象包含目前請求的所有資訊,然後傳遞給HttpRuntime,這裡生成的HttpWorkerRequest對象可以直接在我們的頁面中調用的,通過它取得原始的請求資訊:

IServiceProvider provider = (IServiceProvider)HttpContext.Current;

HttpWorkerRequest wr = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

二:HttpRuntime
最主要的就是private void ProcessRequestInternal(HttpWorkerRequest wr)方法:

context = new HttpContext(wr, false);


IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);


IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance;

context.AsyncAppHandler = handler2;

handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context);

1、根據HttpWorkerRequest對象生成HttpContext,HttpContext應該大家都很熟悉的,它包含request、response等屬性,在頁面中經常會用到的;
2、調用HttpApplicationFactory來生成IHttpHandler(這裡生成的是一個預設的HttpApplication對象,HttpApplication也是IHttpHandler接口的一個實作)
3、調用HttpApplication對象執行請求
三:HttpApplicationFactory
正如2.2中所提 本文轉自永春部落格園部落格,原文連結:,如需轉載請自行聯系原作者到的,這裡主要是生成一個HttpApplication對象:

internal static string GetApplicationFile()
{
return Path.Combine(HttpRuntime.AppDomainAppPathInternal, "global.asax");
}

首先會檢視是否存在global.asax檔案,如果有的話就用它來生成HttpApplication對象,從這裡我們可以看到global.asax的檔案名是在asp.net的架構中寫死的,不能修改的。如果這個檔案不存在就使用預設的對象。
建立好HttpApplication之後對它進行初始化:

application = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType);

using (ApplicationImpersonationContext context2 = new ApplicationImpersonationContext())
application.InitInternal(context, this._state, this._eventHandlerMethods);
四、HttpApplication
這個是比較複雜也比較重要的一個對象
首先是執行初始化操作,比較重要的一步就是進行HttpModule的初始化:

private void InitModules()
this._moduleCollection = RuntimeConfig.GetAppConfig().HttpModules.CreateModules();
this.InitModulesCommon();
它會讀取web.config中所有HttpModule的配置
在HookupEventHandlersForApplicationAndModules方法中綁定Module的事件處理程式接着進行事件實際綁定:

if (HttpRuntime.UseIntegratedPipeline)
this._stepManager = new PipelineStepManager(this);

else
this._stepManager = new ApplicationStepManager(this);

this._stepManager.BuildSteps(this._resumeStepsWaitCallback);
在ApplicationStepManager的BuildSteps方法中可以看到事件的綁定執行順序:

app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);

app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps);

app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, 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());

注意上面紅色标注的MapHandlerExecutionStep(讀取所有的HttpHandler配置)、CallHandlerExecutionStep就是對Handle程式進行處理的,也就是說在web.config中配置的HttpHandler都是在這裡進行處理的,執行順序如上所示
然後就是調用2.3中的方法執行請求:
Code
在ResumeSteps中就是執行事件處理程式。
五、HttpModule
在系統web.config中預設的配置有:
基本使用方法可以參見我的上一篇文章
六、HttpHandlerFactory、HttpHandler
這兩個對象在web.config中的配置方法是相同的,預設配置有:
要注意的是相同的字尾名配置多次的話,後面的配置會把前面的覆寫。
這裡我們重點看一下aspx的配置:System.Web.UI.PageHandlerFactory
這是一個HttpHandlerFactory對象,根據不同的Page生成不同的HttpHandler對象(我們自己的Page頁面都是一個IHttpHandler):

Page page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page), context, true, true) as Page;

if (page == null)
{
return null;
}

page.TemplateControlVirtualPath = virtualPath;

return page;

這裡會調用web.config中的buildProviders配置編譯頁面:
這樣就可以進入我們的Page執行了,大的執行順序可以參見第四部分的描述,它也就是一個HttpHandler.
本文轉自永春部落格園部落格,原文連結:http://www.cnblogs.com/firstyi/archive/2008/05/08/1188545.html,如需轉載請自行聯系原作者