[译] ASP.NET 生命周期 – ASP.NET 上下文对象(六)
使用 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 对象非常困难,我们可以看一下下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing; namespace SimpleApp
{
public class MvcApplication : System.Web.HttpApplication
{
public MvcApplication()
{
PostAcquireRequestState += (src, args) => CreateTimeStamp();
} protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
CreateTimeStamp();
} private void CreateTimeStamp()
{
string stamp = Context.Timestamp.ToLongTimeString();
if (Session != null)
{
Session["request_timestamp"] = stamp;
}
else
{
Application["app_timestamp"] = stamp;
}
}
}
}
现在,我们删除我们之前写的代码,重新定义一个新的方法用来创建时间戳并将其存放在状态数据中。现在,我们不需要对状态数据了解太多,只需要知道 Session 属性会为每一个独立的请求返回状态数据对象。
提示:注意到,我为 PostAcquireRequestState 事件创建了请求时间戳。这是因为模块直到 AcquireRequestState 事件触发之后才会提供状态数据服务。因此,即使全局应用类实例创建出来用来处理请求相关的事件,Session 属性也会返回 null。
这个新方法叫做 CreateTimeStamp,旨在减少代码冗余并为应用层级和请求层级的事件添加事件戳。但是,只要现在应用一启动就会报错,因为在这段代码中,在全局应用类创建出来处理 Application_Start 方法的时候想要尝试读取 Session 属性。
我能够使用 try…catch 代码块,但是这是一个糟糕的实践,因为异常处理不应该用来管理一个应用中可预见的流程。因此,我们应该直接使用 HttpContext 中同等的属性。代码如下:
private void CreateTimeStamp()
{
string stamp = Context.Timestamp.ToLongTimeString();
if (Context.Session != null)
{
Session["request_timestamp"] = stamp;
}
else
{
Application["app_timestamp"] = stamp;
}
}
注意到,我只是修改了之前对 Session 属性的检查;如果它不为 null,我就可以使用 HttpApplication 类中定义的 Session 属性。Application 属性总是能够返回 HttpApplicationState 对象,状态管理相关的知识我们会在后期讲解到。
我们需要注意这种问题特别是在全局应用类中不与独立请求相关联的对象。ASP.NET 其他地方,特别是在 MVC 框架 controller 类中。我们总是可以使用 context 来表示一个请求。我们可以看一下下面的例子:
using SimpleApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace SimpleApp.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(GetTimeStamps());
} [HttpPost]
public ActionResult Index(Color color)
{
Color? oldColor = Session["color"] as Color?;
if (oldColor != null)
{
Votes.ChangeVote(color, (Color)oldColor);
}
else
{
Votes.RecordVote(color);
} ViewBag.SelectedColor = Session["color"] = color;
return View(GetTimeStamps());
} private List<string> GetTimeStamps()
{
return new List<string> { String.Format("App timestamp: {0}", HttpContext.Application["app_timestamp"]),
String.Format("Request timestamp: {0}", Session["request_timestamp"])};
}
}
}
Controller 类是 MVC 框架的基础,当中提供了一个方便的 Session 属性与 HttpContext.Session 相关联(但是我需要使用 HttpContext.Application,因为它并没有相关联的简便的属性)。
你可以在应用启动的时候看到时间戳。因为两个值在起初的时候很可能是相同的,但是如果你重新刷新浏览器窗口的话,你会发现应用时间戳一直不变,而请求时间戳会在每次更新的时候发生改变。
图 1 - 展示应用和请求时间戳
[根据 Adam Freeman – Pro ASP.NET MVC 5 Platform 选译]
[译] ASP.NET 生命周期 – ASP.NET 上下文对象(六)的更多相关文章
- [译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)
概述 ASP.NET 平台定义了两个非常重要的生命周期.第一个是 应用生命周期 (application life cycle),用来追踪应用从启动的那一刻到终止的那一刻.另一个就是 请求生命周期 ...
- [译] ASP.NET 生命周期 – ASP.NET 上下文对象(五)
ASP.NET 上下文对象 ASP.NET 提供了一系列对象用来给当前请求,将要返回到客户端的响应,以及 Web 应用本身提供上下文信息.间接的,这些上下文对象也可以用来回去核心 ASP.NET 框架 ...
- [译] ASP.NET 生命周期 – ASP.NET 上下文对象(七)
使用 HttpRequest 对象 HttpRequest 对象描述的是一个正在被处理的 HTTP 请求.下表列举了 HttpRequest 中的属性,它们提供了当前请求的相关信息(HttpReque ...
- [译] ASP.NET 生命周期 – ASP.NET 请求生命周期(三)
使用特殊方法处理请求生命周期事件 为了在全局应用类中处理这些事件,我们会创建一个名称以 Application_ 开头,以事件名称结尾的方法,比如 Application_BeginRequest.举 ...
- [译] ASP.NET 生命周期 – ASP.NET 请求生命周期(四)
不使用特殊方法来处理请求生命周期事件 HttpApplication 类是全局应用类的基类,定义了可以直接使用的一般 C# 事件.那么使用标准 C# 事件还是特殊方法那就是个人偏好的问题了,如果喜欢, ...
- [译] ASP.NET 生命周期 – ASP.NET 请求生命周期(二)
ASP.NET 请求生命周期 全局应用类也可以用来跟踪每个独立请求的生命周期,包括请求从 ASP.NET 平台传递到 MVC 框架.ASP.NET 框架会创建一个定义在 Global.asax 文件中 ...
- [译] ASP.NET 生命周期 – ASP.NET 上下文对象(八)
使用 HttpResponse 对象 HttpResponse 对象是与 HttpRequest 对象相对应的,用来表示构建中的响应.它当中提供了方法和属性可供我们自定义响应,有一些在使用 MVC 视 ...
- Asp.net生命周期与Http协议
Http协议,底层的东西还是不是特别熟悉,感觉要经过沉淀之后才能理解这些东西吧 1.Asp.net生命周期 Asp.net生命周期: 从发起请求开始,到IIS进行处理的全部过程,然后再到获取结果 当请 ...
- Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用
一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...
随机推荐
- ES 父子文档查询
父子文档的特点 1. 父/子文档是完全独立的. 2. 父文档更新不会影响子文档. 3. 子文档更新不会影响父文档或者其它子文档. 父子文档的映射与索引 1. 父子关系 type 的建立必须在索引新建或 ...
- [转]bat批处理实现TXT文本合并
本文转自:http://quanhuaming.blog.163.com/blog/static/1405693672010210101124905/ 有朋友问是否有可以合并TXT文本文件的软件,于是 ...
- [改善Java代码]列表相等只需关系元素数据
来看一个判断列表相等的例子,看代码: import java.util.ArrayList; import java.util.Vector; public class Client { public ...
- Jquery Easyui验证扩展,Easyui验证,Easyui校验,js正则表达式
Jquery Easyui验证扩展,Easyui验证,Easyui校验,js正则表达式 >>>>>>>>>>>>>> ...
- CSS3—三角形
话不多说看效果:演示效果,runjs 1.加了宽高和border,边用不同颜色显示,每条边都是一个梯形 2.去掉宽高,每条边都是三角形 3.只显示其中一条边就是不同的三角形了,是不是很简单,改变bor ...
- 实用工具推荐(Live Writer)(2015年05月26日)
1.写博客的实用工具 推荐软件:Live Writer 使用步骤: 1.安装 Live Essential 2011,下载地址:http://explore.live.com/windows-live ...
- Spring(3.2.3) - Beans(6): 作用域
Spring 支持五种作用域,分别是 singleton.prototype.request.session 和 global session. 作用域 说明 singleton (默认作用域)单例 ...
- Linux 命令 - wget: 非交互式网络下载器
命令格式 wget [option]... [URL]... 命令参数 启动选项 -V, --version 打印版本信息 -h, --help 打印帮助信息 日志和输入文件选项 -o logfile ...
- 【AngularJs】---Error: [$injector:modulerr] Failed to instantiate module starter.services
[遇到问题解决问题,原谅我这个菜鸟] 加了services angular.module('starter', ['ionic', 'starter.controllers', 'starter.se ...
- 和阿文一起学H5——H5工具、素材
字体: 一般的H5工具都会提供一部分字体,如果提供的字体中没有自己想用的字体,可以在PPT或PS中进行加工,然后另存为图片,再导入到H5工具中去. 字全生成器: 1.http://www.diyizi ...