.NET (C#) Internals: ASP.NET 应用程序与页面生命周期(意译) 1、引言 2、两个处理步骤 2.1、创建ASP.NET环境 2.2、用触发的MHPM事件处理请求 3、什么事件中应该做什么 4、示例代码 5、深入ASP.NET页面事件 1、引言 这篇文章我们将试图理解,从用户发送一个请求直到请求呈现到浏览器发生的事件的差异。因此,我们首先将介绍解ASP.NET请求的两个概括的步骤,接下来我们将介绍‘HttpHandler’,‘HttpModule’和ASP.NET页面对象发出的事件的差异。随着我们的事件旅程,我们将理解这些事件的逻辑。 2、两个处理步骤 ASP.NET请求处理可以总结为如下所示的两个处理步骤。用户发送一个请求到IIS:ASP.NET创建处理请求的环境。换句话说,创建应用程序对象、request、response和context对象去处理请求。 一旦环境已经创建,请求通过使用modules、handlers和page对象的一系列事件处理。为了简化可以称为MHPM(module、handler、page、module event),我们将在后面详细讨论。 图1、ASP.NET请求处理的两个步骤 在接下来的各节,我们将知道更多关于这两个步骤的细节。 2.1、创建ASP.NET环境 step 1:用户发送一个请求到IIS。IIS首先检查哪个ISAPI扩展可以处理这个请求,这取决于请求的文件扩展名。举例来说,如果请求页面是‘.ASPX’,它将被传送到‘aspnet_isapi.dll’来处理。 step 2:如果这是www站点的第一个请求,ApplicationManager类将创建一个应用程序域,www站点运行于其中。我们都知道在同一个IIS上,两个web应用程序的应用程序域是独立的(隔离的)。因此一个应用程序域中问题不会的影响到其它应用程序域。 step 3:新建的应用程序域创建宿主环境,如HttpRuntime对象。一旦宿主环境被创建,必要的ASP.NET核心对象如HttpContext、HttpRequest和HttpRespone对象也被创建。 step 4:一旦所有的ASP.NET核心对象被创建,HttpApplication对象将被创建去处理请求。如果系统中有global.asax文件,global.asax文件对象将被创建。 【注意】:global.asax文件继承自HttpApplication类;第一次ASP.NET页面连接到应用程序,一个HttpApplication新实例将被创建。为了最大化性能,HttpApplication实例可能被多个请求重用。 step 5:接下来HttpApplication对象分配给核心ASP.NET对象来处理页面。 step 6:然后HttpApplication通过HttpContext、HttpRequest和HttpRespone事件开始处理请求。它触发MHPM事件处理请求。【更多细节】:http://msdn.microsoft.com/en-us/library/ms178473.aspx 下图解释了ASP.NET请求的内部对象模型。最高层是ASP.NET运行时,它已经创建一个应用程序域(AppDomain),相应地有HttpRuntime包括request、respone、context对象。 2.2、用触发的MHPM事件处理请求 一旦创建了HttpApplication,它开始处理请求,它经历3个不同的部分HttpModule、Page、HttpHandler。随着它移动到这些部分,将调用不同的事件,开发人员可以扩展和定制同一逻辑。在我们前进之前让我们了解什么是HttpModule和HttpHandlers。他们帮组我们在ASP.NET页处理的前后注入自定义逻辑。他们之间的主要差别是: (1)如果你想要注入的逻辑是基于像‘.ASPX’、‘.HTML’这样的文件扩展名,使用HttpHandler。换句话说HttpHandler是基于处理器的扩展。 (2)如果你想在ASP.NET管道事件中注入逻辑,使用HttpModule。换言之是基于处理器的事件。 你可以点这了解他们之间更多的差异。下面是怎样处理请求的逻辑流。有四个重要的步骤MHPM,解释如下: Step 1(M HttpModule):客户端请求处理开始。ASP.NET引擎开始和创建HttpModule发出事件(你可以注入定制逻辑)之前,有6个重要事件你可以使用:BeginRequest、AuthenticateRequest、AuthorizeRequest、ResolveRequestCache、AcquireRequestState和PreRequestHandlerExecute。 Step 2(H HttpHandler):一旦上面6个事件触发,ASP.NET引擎将调用ProcessRequest事件,即使你已经在项目中执行了HttpHandler。 Step 3(P ASP.NET page):一旦HttpHandler逻辑执行,ASP.NET page对象被创建。ASP.NET page对象被创建,许多事件被触发,你可以在这些页面事件中写我们自定义的逻辑。有6个重要事件给我们提供占位,在ASP.NET页中写逻辑:Init、Load、Validate、Event、Render、Unload。你可以记住单词SILVER来记这些事件,S-Start(没有任何意义,仅仅是为了形成一个单词),I(Init)、L(Load)、V(Validate)、E(Event)、R(Render)。 Step 4(M HttpModule):一旦页面对象执行了且从内存中卸载,HttpModule提供发送页面执行事件,它们可用于注入自定义post-处理逻辑。有4个重要的post-处理事件,PostRequestHandlerExecute、PostRequestState、UpdateRequestCache、EndRequest。 下图展示了上面的过程。 3、什么事件中应该做什么 下面的表格展示了什么事件中做什么逻辑或代码。
4、示例代码 点击下载代码,示例代码展示了事件是怎样触发的。代码中我们创建了一个HttpModule和HttpHandler,且我们显示一个简单的响应在所有的事件中。下面是HttpModule类,跟踪所有的事件且添加到全局集合。 HttpModule类 public class clsHttpModule : IHttpModule { ...... void OnUpdateRequestCache(object sender, EventArgs a) { objArrayList.Add("httpModule:OnUpdateRequestCache"); } void OnReleaseRequestState(object sender, EventArgs a) { objArrayList.Add("httpModule:OnReleaseRequestState"); } void OnPostRequestHandlerExecute(object sender, EventArgs a) { objArrayList.Add("httpModule:OnPostRequestHandlerExecute"); } void OnPreRequestHandlerExecute(object sender, EventArgs a) { objArrayList.Add("httpModule:OnPreRequestHandlerExecute"); } void OnAcquireRequestState(object sender, EventArgs a) { objArrayList.Add("httpModule:OnAcquireRequestState"); } void OnResolveRequestCache(object sender, EventArgs a) { objArrayList.Add("httpModule:OnResolveRequestCache"); } void OnAuthorization(object sender, EventArgs a) { objArrayList.Add("httpModule:OnAuthorization"); } void OnAuthentication(object sender, EventArgs a) { objArrayList.Add("httpModule:AuthenticateRequest"); } void OnBeginrequest(object sender, EventArgs a) { objArrayList.Add("httpModule:BeginRequest"); } void OnEndRequest(object sender, EventArgs a) { objArrayList.Add("httpModule:EndRequest"); objArrayList.Add("<hr>"); foreach (string str in objArrayList) { httpApp.Context.Response.Write(str + "<br>") ; } } } 下面是HttpHandler的代码片段,它跟踪ProcessRequest事件。 public class clsHttpHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { clsHttpModule.objArrayList.Add("HttpHandler:ProcessRequest"); context.Response.Redirect("Default.aspx"); } } 我们也追踪ASP.NET页面的所有事件。 public partial class _Default : System.Web.UI.Page { protected void Page_init(object sender, EventArgs e) { clsHttpModule.objArrayList.Add("Page:Init"); } protected void Page_Load(object sender, EventArgs e) { clsHttpModule.objArrayList.Add("Page:Load"); } public override void Validate() { clsHttpModule.objArrayList.Add("Page:Validate"); } protected void Button1_Click(object sender, EventArgs e) { clsHttpModule.objArrayList.Add("Page:Event"); } protected override void Render(HtmlTextWriter output) { clsHttpModule.objArrayList.Add("Page:Render"); base.Render(output); } protected void Page_Unload(object sender, EventArgs e) { clsHttpModule.objArrayList.Add("Page:UnLoad"); }} 下面显示上面讨论的所有事件的执行顺序: 5、深入ASP.NET页面事件 在前面部分我们已经知道ASP.NET页面请求的整体事件流,但是我们没有详细讨论,因此本节我们将深入了解。任何ASP.NET页面有2个部分,一个是显示在浏览器上的页面,它有HTML标记、viewstate形式的隐藏值、HTML inputs上的数据。当页面被发送时,在服务器上这些HTML标记被创建到ASP.NET控件且viewstate和表单数据捆绑在一起。一旦你得到这些服务器控件的后台代码,你可以执行和写你自己的逻辑和呈现返回给浏览器。 现在这些HTML控件在服务器上作为ASP.NET控件,ASP.NET页面发出一些事件,我们可以注入自己的逻辑。根据任务/你要执行的逻辑,我们需要把这些逻辑放入适当的事件中。 【注意】:大部分开发者直接使用Page_Load方法执行一切,这不是一个好的方法。因此,不是填充控件、设置viewstate、应用主题等一切都发生在页面加载上。因此,如果我们能在适当的事件中放入逻辑,将真正使你的代码干净。、
.NET Framework 4 - ASP.NET 1 ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0This topic outlines the life cycle of ASP.NET applications, listing important life-cycle events and describing how code that you write can fit into the application life cycle. The information in this topic applies to IIS 5.0 and IIS 6.0. For information about the ASP.NET application life cycle in IIS 7.0, see ASP.NET Application Life Cycle Overview for IIS 7.0. Within ASP.NET, several processing steps must occur for an ASP.NET application to be initialized and process requests. Additionally, ASP.NET is only one piece of the Web server architecture that services requests made by browsers. It is important for you to understand the application life cycle so that you can write code at the appropriate life cycle stage for the effect you intend. Application Life Cycle in General The following table describes the stages of the ASP.NET application life cycle.
Life Cycle Events and the Global.asax file During the application life cycle, the application raises events that you can handle and calls particular methods that you can override. To handle application events or methods, you can create a file named Global.asax in the root directory of your application. If you create a Global.asax file, ASP.NET compiles it into a class derived from the HttpApplication class, and then uses the derived class to represent the application. An instance of HttpApplication processes only one request at a time. This simplifies application event handling because you do not need to lock non-static members in the application class when you access them. This also allows you to store request-specific data in non-static members of the application class. For example, you can define a property in the Global.asax file and assign it a request-specific value. ASP.NET automatically binds application events to handlers in the Global.asax file using the naming convention Application_event, such as Application_BeginRequest. This is similar to the way that ASP.NET page methods are automatically bound to events, such as the page's Page_Load event. For details, see ASP.NET Page Life Cycle Overview. The Application_Start and Application_End methods are special methods that do not represent HttpApplication events. ASP.NET calls them once for the lifetime of the application domain, not for each HttpApplication instance. The following table lists some of the events and methods that are used during the application life cycle. There are many more events than those listed, but they are not commonly used.
Compilation Life Cycle When the first request is made to an application, ASP.NET compiles application items in a specific order. The first items to be compiled are referred to as the top-level items. After the first request, the top-level items are recompiled only if a dependency changes. The following table describes the order in which ASP.NET top-level items are compiled.
After the application's top level items have been compiled, ASP.NET compiles folders, pages, and other items as needed. The following table describes the order in which ASP.NET folders and items are compiled.
Compiled assemblies are cached on the server and reused on subsequent requests and are preserved across application restarts as long as the source code is unchanged. Because the application is compiled on the first request, the initial request to an application can take significantly longer than subsequent requests. You can precompile your application to reduce the time required for the first request. For more information, see How to: Precompile ASP.NET Web Sites. Application Restarts
Modifying the source code of your Web application will cause ASP.NET to recompile source files into assemblies. When you modify the top-level items in your application, all other assemblies in the application that reference the top-level assemblies are recompiled as well. In addition, modifying, adding, or deleting certain types of files within the application's known folders will cause the application to restart. The following actions will cause an application restart: · Adding, modifying, or deleting assemblies from the application's Bin folder. · Adding, modifying, or deleting localization resources from the App_GlobalResources or App_LocalResources folders. · Adding, modifying, or deleting the application's Global.asax file. · Adding, modifying, or deleting source code files in the App_Code directory. · Adding, modifying, or deleting Profile configuration. · Adding, modifying, or deleting Web service references in the App_WebReferences directory. · Adding, modifying, or deleting the application's Web.config file. When an application restart is required, ASP.NET will serve all pending requests from the existing application domain and the old assemblies before restarting the application domain and loading the new assemblies. HTTP Modules The ASP.NET application life cycle is extensible through IHttpModule classes. ASP.NET includes several classes that implement IHttpModule, such as the SessionStateModule class. You can also create your own classes that implement IHttpModule. If you add modules to your application, the modules themselves can raise events. The application can subscribe to in these events in the Global.asax file by using the convention modulename_eventname. For example, to handle the Authenticate() event raised by a FormsAuthenticationModule object, you can create a handler named FormsAuthentication_Authenticate. The SessionStateModule class is enabled by default in ASP.NET. All session events are automatically wired up as Session_event, such as Session_Start. The Start() event is raised each time a new session is created. For more information, see ASP.NET Session State Overview.
|
|