您的位置:首页 > 编程语言 > ASP

Asp.Net页面执行流程分析

2008-05-14 12:51 357 查看
Asp.Net页面执行流程分析
在我的上一篇文章中说到了HttpModule、HttpHandle的简单使用,我们可以利用它们在页面请求的过程中加入自己的事件处理程序。那么在一个aspx页面请求时后台到底做了什么?当然asp.net做了很多事情,过程也比较复杂,本文主要分析一下大体的流程。总体流程如下:

请求一个页面时首先被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))

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);

internal static string GetApplicationFile()

首先会查看是否存在global.asax文件,如果有的话就用它来生成HttpApplication对象,从这里我们可以看到global.asax的文件名是在asp.net的框架中写死的,不能修改的。如果这个文件不存在就使用默认的对象。

创建好HttpApplication之后对它进行初始化:

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

using (ApplicationImpersonationContext context2 = new ApplicationImpersonationContext())

private void InitModules()

if (HttpRuntime.UseIntegratedPipeline)

else

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中的方法执行请求:

IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)

在ResumeSteps中就是执行事件处理程序。



五、HttpModule


在系统web.config中默认的配置有:

<httpModules>

<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>

<add name="Session" type="System.Web.SessionState.SessionStateModule"/>

<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>

<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>

<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule"/>

<add name="RoleManager" type="System.Web.Security.RoleManagerModule"/>

<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>

<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/>

<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule"/>

<add name="Profile" type="System.Web.Profile.ProfileModule"/>

<add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>

<add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

</httpModules>

基本使用方法可以参见我的上一篇文章



六、HttpHandlerFactory、HttpHandler


这两个对象在web.config中的配置方法是相同的,默认配置有:

<add path="*.rules" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.xoml" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>

<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 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.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="false"/>

<add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>

<add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=2.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"/>

<add path="*.exe.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="true"/>

<add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.cs" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.csproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.vb" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.vbproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.webinfo" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.licx" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.resx" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.resources" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.mdb" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.vjsproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.java" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.jsl" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.ldb" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.ad" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.dd" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.ldd" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.sd" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.cd" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.adprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.lddprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.sdm" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.sdmDocument" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.mdf" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.ldf" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.exclude" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.refresh" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

<add path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>

<add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="true"/>

<add path="*" verb="*" type="System.Web.HttpMethodNotAllowedHandler" validate="true"/>

</httpHandlers>

要注意的是相同的后缀名配置多次的话,后面的配置会把前面的覆盖。

这里我们重点看一下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)

page.TemplateControlVirtualPath = virtualPath;

return page;

这里会调用web.config中的buildProviders配置编译页面:

<buildProviders>

<add extension=".aspx" type="System.Web.Compilation.PageBuildProvider"/>

<add extension=".ascx" type="System.Web.Compilation.UserControlBuildProvider"/>

<add extension=".master" type="System.Web.Compilation.MasterPageBuildProvider"/>

<add extension=".asmx" type="System.Web.Compilation.WebServiceBuildProvider"/>

<add extension=".ashx" type="System.Web.Compilation.WebHandlerBuildProvider"/>

<add extension=".soap" type="System.Web.Compilation.WebServiceBuildProvider"/>

<add extension=".resx" type="System.Web.Compilation.ResXBuildProvider"/>

<add extension=".resources" type="System.Web.Compilation.ResourcesBuildProvider"/>

<add extension=".wsdl" type="System.Web.Compilation.WsdlBuildProvider"/>

<add extension=".xsd" type="System.Web.Compilation.XsdBuildProvider"/>

<add extension=".js" type="System.Web.Compilation.ForceCopyBuildProvider"/>

<add extension=".lic" type="System.Web.Compilation.IgnoreFileBuildProvider"/>

<add extension=".licx" type="System.Web.Compilation.IgnoreFileBuildProvider"/>

<add extension=".exclude" type="System.Web.Compilation.IgnoreFileBuildProvider"/>

<add extension=".refresh" type="System.Web.Compilation.IgnoreFileBuildProvider"/>

<add extension=".xoml" type="System.ServiceModel.Activation.WorkflowServiceBuildProvider, System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add extension=".svc" type="System.ServiceModel.Activation.ServiceBuildProvider, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

</buildProviders>

这样就可以进入我们的Page执行了,大的执行顺序可以参见第四部分的描述,它也就是一个HttpHandler.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: