你的位置:首页 > ASP.net教程

[ASP.net教程][译] 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.HttpApplication11   {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 }

View Code

我定义了一个叫做 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 : Controller11   {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       else27       {28         Votes.RecordVote(color);29       }30 31       ViewBag.SelectedColor = Session["color"] = color;32       return View(HttpContext.Application["events"]);33     }34   }35 }

View Code

为了获取到存储在全局应用类中的数据,我们需要使用到 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     else25     {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>

View Code

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

展示生命周期事件详情

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

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

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