[译] ASP.NET 生命周期 – ASP.NET 上下文对象(六)-阿里云开发者社区

开发者社区> 浅蓝丶遠行> 正文

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

简介: 使用 HttpApplication 对象 ASP.NET 框架中的许多类都提供了许多很方便的属性可以直接映射到 HttpContext 类中定义的属性。这种交叠有一个很好的例子就是 HttpApplication,它就是全局应用类的基类,在下表中,你可以看到 HttpApplication 类中定义的属性和方法。
+关注继续查看

使用 HttpApplication 对象

ASP.NET 框架中的许多类都提供了许多很方便的属性可以直接映射到 HttpContext 类中定义的属性。这种交叠有一个很好的例子就是 HttpApplication,它就是全局应用类的基类,在下表中,你可以看到 HttpApplication 类中定义的属性和方法。许多和 HttpContext 中定义的很相似。

表 1 – HttpApplication 类中定义的成员

名称 描述
Application 对应到 HttpContext.Application 属性,通过它可以获取应用层面的状态数据。
CompleteRequest() 终止当前请求的生命周期,直接跳转到 LogRequest 事件。
Context 返回当前请求的 HttpContext 对象。
Init() 每个注册模块上的 Init() 方法调用之后调用。
Modules 返回一个 HttpModuleCollection 对象,当中详细描述了当前应用中的模块。
RegisterModule(type) 注册新模块的静态方法。
Request 返回 HttpContext.Request 值, 但是如果值为 null 的时候会抛出一个 HttpException。
Response 返回 HttpContext.Response 值,但是如果值为 null 的时候会抛出一个 HttpException。
Server 映射到 HttpContext.Server。
Session 返回 HttpContext.Session 值,但是如果值为 null 的时候会抛出一个 HttpException。

大多数的这些成员都是很方便的属性可以映射到 HttpContext 类中的属性,但是有三个值得注意,接下来详细说明。

处理属性异常

Request, Response, Session 和 User 属性返回的是 HttpContext 类中相对应的属性的值,但是,这些属性如果从 HttpContext 上对应的属性中获取的值是 null 就会抛出一个 HttpException。

发生这样的事是因为 HttpApplication 类会为两种不同的生命周期接收通知:应用生命周期和请求生命周期。描述单个请求的对象是不可以在全局应用类中用来处理应用相关的事件,所以如果我们在处理应用层级的通知的时候使用了与请求相关联的属性就会抛出 HttpException 异常。

抛出这样一个异常的策略是非常粗糙的,因为这使得处理未知来源的 HttpApplication 对象非常困难,我们可以看一下下面的代码:

 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         public MvcApplication()
13         {
14             PostAcquireRequestState += (src, args) => CreateTimeStamp();
15         }
16 
17         protected void Application_Start()
18         {
19             AreaRegistration.RegisterAllAreas();
20             RouteConfig.RegisterRoutes(RouteTable.Routes);
21             CreateTimeStamp();
22         }
23 
24         private void CreateTimeStamp()
25         {
26             string stamp = Context.Timestamp.ToLongTimeString();
27             if (Session != null)
28             {
29                 Session["request_timestamp"] = stamp;
30             }
31             else
32             {
33                 Application["app_timestamp"] = stamp;
34             }
35         }
36     }
37 }
View Code

现在,我们删除我们之前写的代码,重新定义一个新的方法用来创建时间戳并将其存放在状态数据中。现在,我们不需要对状态数据了解太多,只需要知道 Session 属性会为每一个独立的请求返回状态数据对象。

提示:注意到,我为 PostAcquireRequestState 事件创建了请求时间戳。这是因为模块直到 AcquireRequestState 事件触发之后才会提供状态数据服务。因此,即使全局应用类实例创建出来用来处理请求相关的事件,Session 属性也会返回 null。

这个新方法叫做 CreateTimeStamp,旨在减少代码冗余并为应用层级和请求层级的事件添加事件戳。但是,只要现在应用一启动就会报错,因为在这段代码中,在全局应用类创建出来处理 Application_Start 方法的时候想要尝试读取 Session 属性。

我能够使用 try…catch 代码块,但是这是一个糟糕的实践,因为异常处理不应该用来管理一个应用中可预见的流程。因此,我们应该直接使用 HttpContext 中同等的属性。代码如下:

 1 private void CreateTimeStamp()
 2 {
 3     string stamp = Context.Timestamp.ToLongTimeString();
 4     if (Context.Session != null)
 5     {
 6         Session["request_timestamp"] = stamp;
 7     }
 8     else
 9     {
10         Application["app_timestamp"] = stamp;
11     }
12 }
View Code

注意到,我只是修改了之前对 Session 属性的检查;如果它不为 null,我就可以使用 HttpApplication 类中定义的 Session 属性。Application 属性总是能够返回 HttpApplicationState 对象,状态管理相关的知识我们会在后期讲解到。

我们需要注意这种问题特别是在全局应用类中不与独立请求相关联的对象。ASP.NET 其他地方,特别是在 MVC 框架 controller 类中。我们总是可以使用 context 来表示一个请求。我们可以看一下下面的例子:

 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(GetTimeStamps());
15         }
16         
17         [HttpPost]
18         public ActionResult Index(Color color)
19         {
20             Color? oldColor = Session["color"] as Color?;
21             if (oldColor != null)
22             {
23                 Votes.ChangeVote(color, (Color)oldColor);
24             }
25             else
26             {
27                 Votes.RecordVote(color);
28             }
29 
30             ViewBag.SelectedColor = Session["color"] = color;
31             return View(GetTimeStamps());
32         }
33 
34         private List<string> GetTimeStamps()
35         {
36             return new List<string> { String.Format("App timestamp: {0}", HttpContext.Application["app_timestamp"]),
37                 String.Format("Request timestamp: {0}", Session["request_timestamp"])};
38         }
39     }
40 }
View Code

Controller 类是 MVC 框架的基础,当中提供了一个方便的 Session 属性与 HttpContext.Session 相关联(但是我需要使用 HttpContext.Application,因为它并没有相关联的简便的属性)。

你可以在应用启动的时候看到时间戳。因为两个值在起初的时候很可能是相同的,但是如果你重新刷新浏览器窗口的话,你会发现应用时间戳一直不变,而请求时间戳会在每次更新的时候发生改变。

3.7 Displaying application and request timestamps

图 1 - 展示应用和请求时间戳

 

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
消灭“脑细胞杀手”,阿里专家带你深入C++对象的生命周期管理
C/C++的指针一直是令人又爱又恨的特性。围绕指针产生了许许多多优雅的数据结构和系统实现,但又滋生了不少“脑细胞杀手”——内存Bug。如何通过指针管理C++中对象,如何管理对象的生命周期呢?本文中,阿里巴巴高级开发工程师付哲就为大家分享《C++对象的生命周期管理》。
4277 0
未能初始化 PassportManager 对象。请确保在服务器上正确安装了 Microsoft Passport。
未能初始化 PassportManager 对象。请确保在服务器上正确安装了 Microsoft Passport。 已经不记得 Microsoft Passport 怎么使用了,也没有查到 Microsoft Passport 的安装方法。
802 0
《你必须知道的.net》读书笔记 001——1.1 对象的旅行
    好久没看书了,上次看书的时候还是一年前了,一个偶然的机会,比较系统的看了一下OO的基础,封装、继承、多态等,当时真的是很不会,看了也是一知半解,迷迷糊糊的。在实际中的项目里也没敢一下子应用OO,还是用自己比较拿手的面向过程来应对项目,然后一点一点使用OO的技巧来代替一部分的代码(或者叫做功能)。
748 0
JSP第四篇【EL表达式介绍、获取各类数据、11个内置对象、执行运算、回显数据、自定义函数、fn方法库】
什么是EL表达式? 表达式语言(Expression Language,EL),EL表达式是用"${}"括起来的脚本,用来更方便的读取对象! EL表达式主要用来读取数据,进行内容的显示! 为什么要使用EL表达式? 为什么要使用EL表达式,我们先来看一下没有EL表达式是怎么样读取对象数据的吧! 在1.
1147 0
.NET对象的XML序列化和反序列化
 序列化的概念 序列化是指一个对象的实例可以被保存,保存成一个二进制串,当然,一旦被保存成二进制串,那么也可以保存成文本串了。比如,一个计数器,数值为2,我们可以用字符串“2”表示。如果有个对象,叫做connter,当前值为2,那么可以序列化成“2”,反向的,也可以从“2”得到值为2的计数器实例。
718 0
16
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载