[译] ASP.NET 生命周期 – ASP.NET 请求生命周期(三)

使用特殊方法处理请求生命周期事件

为了在全局应用类中处理这些事件,我们会创建一个名称以 Application_ 开头,以事件名称结尾的方法,比如 Application_BeginRequest。举个例子,就像 Application_Start 和 Application_End 方法,ASP.NET 框架就会在事件触发的时候找到这些函数并触发它。下面是更新后的代码片段:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 using System.Web.Routing;
 7
 8 namespace SimpleApp
 9 {
10     public class MvcApplication : System.Web.HttpApplication
11     {
12         protected void Application_Start()
13         {
14             AreaRegistration.RegisterAllAreas();
15             RouteConfig.RegisterRoutes(RouteTable.Routes);
16         }
17
18         protected void Application_BeginRequest()
19         {
20             RecordEvent("BeginRequest");
21         }
22
23         protected void Application_AuthenticateRequest()
24         {
25             RecordEvent("AuthenticateRequest");
26         }
27
28         protected void Application_PostAuthenticateRequest()
29         {
30             RecordEvent("PostAuthenticateRequest");
31         }
32
33         private void RecordEvent(string name)
34         {
35             List<string> eventList = Application["events"] as List<string>;
36             if (eventList == null)
37             {
38                 Application["events"] = eventList = new List<string>();
39             }
40             eventList.Add(name);
41         }
42     }
43 }

我定义了一个叫做 RecordEvent 的方法,用来接收一个事件的名称作为参数,并将其存储到 HttpApplication 类的 Application 属性中。

注意:在没有深入了解 Application 属性之前,请勿滥用这个属性。

我从添加到全局应用类中的其他三个方法中调用了 RecordEvent 方法。这些方法会在 BeginRequest, AuthenticateRequest 和 PostAuthenticateRequest 触发的时候被调用。我们暂时不需要将这些函数显式注册成事件处理器,ASP.NET 框架会自动定位和调用这些函数。

展示事件信息

为了展示我们代码中接收到的事件的信息,我们需要更改 Home controller 和它的 Index 视图。代码如下:

 1 using SimpleApp.Models;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Mvc;
 7
 8 namespace SimpleApp.Controllers
 9 {
10     public class HomeController : Controller
11     {
12         public ActionResult Index()
13         {
14             return View(HttpContext.Application["events"]);
15         }
16
17         [HttpPost]
18         public ActionResult Index(Color color)
19         {
20             Color? oldColor = Session["color"] as Color?;
21
22             if (oldColor != null)
23             {
24                 Votes.ChangeVote(color, (Color)oldColor);
25             }
26             else
27             {
28                 Votes.RecordVote(color);
29             }
30
31             ViewBag.SelectedColor = Session["color"] = color;
32             return View(HttpContext.Application["events"]);
33         }
34     }
35 }

为了获取到存储在全局应用类中的数据,我们需要使用到 HttpContext.Application 属性,我们后面会详细讲解上下文对象。现在,我们需要更新相关的 Razor 视图:

 1 @using SimpleApp.Models
 2 @model List<string>
 3 @{
 4     Layout = null;
 5 }
 6
 7 <!DOCTYPE html>
 8
 9 <html>
10 <head>
11     <meta charset="utf-8" />
12     <meta name="viewport" content="width=device-width" />
13     <title>Vote</title>
14     <link rel="stylesheet" href="~/Content/bootstrap.min.css" />
15     <link rel="stylesheet" href="~/Content/bootstrap-theme.min.css" />
16 </head>
17 <body class="container">
18     <div class="panel panel-primary">
19
20         @if (ViewBag.SelectedColor == null)
21         {
22             <h4 class="panel-heading">Vote for your favourite color</h4>
23         }
24         else
25         {
26             <h4 class="panel-heading">Change your vote from @ViewBag.SelectedColor</h4>
27         }
28
29         <div class="panel-body">
30             @using (Html.BeginForm())
31             {
32                 @Html.DropDownList("color", new SelectList(Enum.GetValues(typeof(Color))), "Choose a Color", new { @class = "form-control" })
33
34                 <div>
35                     <button class="btn btn-primary center-block" type="submit">Vote</button>
36                 </div>
37             }
38         </div>
39     </div>
40
41     <div class="panel panel-primary">
42         <h5 class="panel-heading">Results</h5>
43
44         <table class="table table-striped table-condensed">
45             <tr>
46                 <th>Color</th>
47                 <th>Votes</th>
48             </tr>
49             @foreach (Color c in Enum.GetValues(typeof(Color)))
50             {
51                 <tr>
52                     <td>@c</td>
53                     <td>@Votes.GetVotes(c)</td>
54                 </tr>
55             }
56         </table>
57     </div>
58
59     <div class="panel panel-primary">
60         <h5 class="panel-heading">Events</h5>
61         <table class="table table-condensed table-striped">
62             @foreach (string eventName in Model)
63             {
64                 <tr><td>@eventName</td></tr>
65             }
66         </table>
67     </div>
68 </body>
69 </html>

事件名称列表作为模型对象传递到视图中,我们使用 Razor foreach 循环来生成 HTML table 元素。

图 1 - 展示生命周期事件详情

提示:这种技术只能使用在排在 PreRequestHandlerExecute 事件之前的事件之上,因为 controller 中的 action 方法会在 PreRequestHandlerExecute 和 PostRequestHandlerExecute 事件之间执行,所以后续触发的事件都已经在响应生成好之后发生了。

[根据 Adam Freeman – Pro ASP.NET MVC 5 Platform 选译]

时间: 2024-10-23 15:04:34

[译] ASP.NET 生命周期 – ASP.NET 请求生命周期(三)的相关文章

[译] ASP.NET 生命周期 – ASP.NET 请求生命周期(四)

不使用特殊方法来处理请求生命周期事件 HttpApplication 类是全局应用类的基类,定义了可以直接使用的一般 C# 事件.那么使用标准 C# 事件还是特殊方法那就是个人偏好的问题了,如果喜欢,也可以将这两种方式混合起来使用. 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.W

[译] ASP.NET 生命周期 – ASP.NET 上下文对象(五)

ASP.NET 上下文对象 ASP.NET 提供了一系列对象用来给当前请求,将要返回到客户端的响应,以及 Web 应用本身提供上下文信息.间接的,这些上下文对象也可以用来回去核心 ASP.NET 框架特性. 上下文对象提供了应用,当前请求,与当前请求相关联的响应的信息.也提供了对多数重要的 ASP.NET 平台服务的访问,比如安全与状态数据.我们可以在 MVC 框架的 controllers 和 views 中使用上下文对象来根据当前的请求或者应用状态数据来调整我们应用的响应.在创建模块或者处理

详解ASP.NET MVC的请求生命周期

本文的目的旨在详细描述asp.net mvc请求从开始到结束的每一个过程. 我希望能理解在浏览器输入url并敲击回车来请求一个asp.net mvc网站的页面之后发生的任何事情. 为什么需要关心这些?有两个原因.首先是因为asp.net mvc是一个扩展性非常强的框架.例如,我们可以插入不同的viewengine来控制网站内容呈现的方式.我们还可以定义控制器生成和分配到某个请求的 方式.因为我想发掘任何asp.net mvc页面请求的扩展点,所以我要来探究请求过程中的一些步骤. 其次,如果你对测

ASP.NET MVC深度接触:ASP.NET MVC请求生命周期

这篇博文的目的旨在详细描述ASP.NET MVC 请求从开始到结束的每一个过程.我希望能理解在浏览器输入URL 并敲击回车来请求一个ASP.NET MVC 网站的页面之后发生的任何事情. 为什么需要关心这些?有两个原因.首先是因为ASP.NET MVC 是一个扩展性非常强的框架.例如,我们可以插入不同的ViewEngine 来控制网站内容呈现的方式.我们还可以定义控制器生成和分配到某个请求的方式.因为我想发掘任何ASP.NET MVC 页面请求的扩展点,所以我要来探究请求过程中的一些步骤. 其次

【MVC】ASP.NET MVC 请求生命周期

当一个asp.net mvc应用程序提出请求,为了响应请求,包含一些请求执行流程步骤! 在asp.net mvc应用程序Http request和Http response 过程中,主要包含8个步骤: 1)RouteTable(路由表)的创建      2)UrlRoutingModule 请求拦截      3)Routing engine 确定route      4)route handler 创建相关的IHttpHandler实例      5)IHttpHandler实例确定Contr

ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

概述 ASP.NET 平台定义了两个非常重要的生命周期.第一个是 应用生命周期  (application life cycle),用来追踪应用从启动的那一刻到终止的那一刻.另一个就是 请求生命周期 (request life cycle),它定义了 HTTP 请求在 ASP.NET 平台中首次接收到,到最终响应发出之间的路径. ASP.NET 应用生命周期 在 ASP.NET 中有两个时刻——应用启动的时刻和应用停止接收请求的时刻,这两个时刻定义了应用生命周期.ASP.NET 在应用启动和当应

ASP.NET页面生命周期与控件生命周期

ASP.NET页面生命周期 (1)PreInit 预初始化(2)Init 初始化(3)InitComplete 初始化完成(4)PreLoad 预加载(5)Load 加载(6)LoadComplete 加载完成(7)PreRender 预输出(8)PreRenderComplete 预输出完成(9)Unload 卸载 ASP.NET控件生命周期 -- 实例化(Instantiate) 控件被页面或另一个控件通过调用它的构造器所实例化.这个步骤之后所列出的阶段,仅当控件加入控件树中才会发生. --

atitit.提升开发效率---使用服务器控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比较

atitit.提升开发效率---使用服务器控件生命周期  asp.net 11个阶段  java jsf 的6个阶段比较 如下列举了服务器控件生命周期所要经历的11个阶段. (1)初始化-- --在此阶段中,主要完成两项工作:一.初始化在传入Web请求生命周期内所需的设置:二.跟踪视图状态.首先,页面框架通过默认方式引发Init事件, 并调用OnInit()方法,控件开发人员可以重写该方法为控件提供初始化逻辑.此后,页面框架将调用TrackViewState方法来跟踪视图状态. 需要注意的是:多

ASP.NET Web 应用程序及页面生命周期

以客户端浏览器向 ASP.NET Web 应用程序页面发送请求(Request)为起点,以浏览器收到 Web 服务器的响应(Response)为终点,这一完整的过程被称为"应用程序及页面的生命周期". ASP.NET Web 页面生命周期开始之前发生了什么? 用户浏览器向 Web 服务器(IIS)发出资源的请求. Web 服务器收到请求,会根据请求文件的扩展名(如 .aspx..ascx..ashx..asmx),指定 ISAPI 扩展来处理该请求,这里提到的扩展名将会由 aspnet