ASP.NET 上下文对象

ASP.NET 提供了一系列对象用来给当前请求,将要返回到客户端的响应,以及 Web 应用本身提供上下文信息。间接的,这些上下文对象也可以用来回去核心 ASP.NET 框架特性。

上下文对象提供了应用,当前请求,与当前请求相关联的响应的信息。也提供了对多数重要的 ASP.NET 平台服务的访问,比如安全与状态数据。我们可以在 MVC 框架的 controllers 和 views 中使用上下文对象来根据当前的请求或者应用状态数据来调整我们应用的响应。在创建模块或者处理器的时候,我们也会使用到这些对象。基于 ASP.NET 服务(比如移动设备侦测),MVC 框架使用上下文对象来处理请求。

理解 ASP.NET 上下文对象

上下文的核心类就是 System.Web.HttpContext。它在整个 ASP.NET 框架和 MVC 框架中都可见,并且它扮演了通向其他上下文对象和 ASP.NET 特性与服务的入口。事实上,在 ASP.NET 框架,HttpContext 类是很核心的,它当中的许多重要属性在接下来都会讲到。

表 1 - 最常使用的 HttpContext 成员

名称 描述
Application 返回 HttpApplicationState 对象,用来管理应用状态数据。
ApplicationInstance 返回与当前请求相关联的 HttpApplication 对象。
Cache 返回一个 Cache 对象用来缓存数据。
Current (静态)返回当前请求的 HttpContext 对象。
CurrentHanlder 返回 IHttpHanlder 实例用来为当前请求生成内容。
IsDebuggingEnabled 如果调试器附加到了 ASP.NET 应用中就会返回 true。我们可以使用这个来执行与调试相关的活动,但是,如果我们这么做,切记要在部署之前没有调试器的情况下测试完整。
Items 返回一个集合可以用来在参与当前请求处理的组件之前传递状态数据。
GetSection(name) 获取 Web.config 文件中指定的配置块。
Request 返回一个 HttpRequest 对象用来提供当前正在被处理的请求的详细信息。
Response 返回一个 HttpResponse 对象用来提供当前正在构建的并即将发送到浏览器的响应的详细信息。
Session 返回一个 HttpSession 对象用来提供对会话状态的访问。在 PostAcquireRequestState 应用事件触发之前,这个属性只会返回 null。
Server 返回一个 HttpServerUtility 对象,当中包含了实用函数,最实用的就是请求处理器的执行。
Timestamp 返回一个 DateTime 对象,当中包含了 HttpContext 对象创建时的时间。
Trace 用来记录诊断信息。

HttpContext 也定义了方法和属性可以用来管理请求生命周期——比如 CurrentNotification 和 IsPostNotification 属性。接下来将会介绍其他的上下文对象特性,包括由 HttpContext 定义的。

我们可以在全局应用类中通过 Context 属性获取到 HttpContext 类的实例。这个属性的名称并不是全局的。在 controller 类中或者一个视图中,我们需要使用 HttpContext 属性来获取。如果这些方式都失败了,那么我们就可以使用静态的 HttpContext.Current 来获取与当前请求相关联的 HttpContext 对象。

表 2 - 在不同的 ASP.NET/MVC 组件中获取一个 HttpContext 实例

组件 技术
Controller 使用 Controller 中定义的 HttpContext 属性,它是 MVC 框架中 controllers 的基类。
View 使用 WebViewPage 中定义的 Context 属性,它是用来编译 Razor 视图的基类。
Global Application Class 使用 HttpApplication 中定义的一个方便的属性——Context。
Module 当调用的时候会在 Init 方法中传递一个 HttpContext 对象,生命周期事件处理器被传递给一个 HttpApplication 对象,这个对象当中定义了一个 Context 属性。
Handler ProceeRequest 方法被调用的时候会传递一个 HttpContext 对象。
Universally 我们总是可以通过 HttpContext.Current 属性来获取到与当前请求相关的 HttpContext 对象。

提示:每个请求都会创建一系列新的上下文对象,当我们获取到 HttpRequest 或者 HttpResponse 对象的时候,我们都会获取到一个与当前请求相关联的全局应用类实例。或者,换句话说,我们不需要担心定位某个指定请求的上下文对象。

注意到,在上表中我并没有将应用组件包括在内。你可以通过静态 HttpContext.Current 属性来获取当前请求的 HttpContext 对象,但是,我建议不要使用,因为这在模型与 controller 之前模糊了关注点分离这个原则。如果一个模型需要一个请求的相关信息,那么我们可以通过从 controller 中的上下文对象中获取这些信息,将其作为一个方法的参数传递给模型就行。这就确保了模型不会介入 controllers 的业务之中,这也使得模型可以进行单元测试,而不需要有任何 ASP.NET 或者 MVC 框架的引用。

Context, Base, 和 Wrapper 类

上表中列出的属性并不会都返回相同的类型。在非 MVC 框架的组件(全局应用类,处理器,和模块)中的属性返回的是一个 HttpContext 对象,基本上就是我们预期想要的。

这些在 MVC 框架诞生之前的上下文对象使得代码很难进行单元测试,因为它们的耦合度很高,需要我们每次在进行测试之前创建一整套上下文对象,比较繁琐。

在 MVC 框架中定义的组件的属性——controller 和 view,可以用来获取上下文对象并且返回继承于上下文类的不同类的实例,这提供了很容易的单元测试。Controller 类中的 HttpContext 属性返回了一个 HttpContextBase 类的实例,所有的上下文对象都是由一个以 Base 为后缀的类表示的(HttpRequestContext, HttpResponseContext, 等等),它们更容易实例化,配置和进行单元测试。

我们有时候需要根据 ASP.NET 对象创建一个 Base 对象。比如,我们有一个对象,但是需要调用一个以 HttpResponseBase 对象为参数的方法。ASP.NET 类库中包括了以 Wrapper 为后缀的类:HttpContextWrapper,HttpRequestWrapper,等等。这些类继承自 Base 类,在 MVC 中以一个 MVC 友好的 Base 类方式表示 ASP.NET 上下文类(所以 HttpContextWrapper 是继承自 HttpContextBase,它接收一个 HttpContext 实例作为构造器参数)。Wrapper 类构造器以上下文对象作为构造器参数,并将 HttpContextWrapper 的属性,方法传递给它当中包含的 HttpContext 实例。

我们不能对一个 Base 对象进行拆包——比如将 HttpRequestBase 转换成 HttpRequest。但是我们总能够通过静态的 HttpContext.Current 获取到我们需要的的上下文对象,它会返回一个 HttpContext 对象。在 controller 中我们需要为这个属性使用完整的名称(System.Web.HttpContext.Current),因为在当中定义了一个 HttpContext 属性,但是返回的是 HttpContextBase 对象。其实,我将 ASP.NET 框架的上下文类与 MVC Base 类视为等同的。

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

[译] ASP.NET 生命周期 – ASP.NET 上下文对象(五)的更多相关文章

  1. [译] ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

    概述 ASP.NET 平台定义了两个非常重要的生命周期.第一个是 应用生命周期  (application life cycle),用来追踪应用从启动的那一刻到终止的那一刻.另一个就是 请求生命周期 ...

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

    使用 HttpApplication 对象 ASP.NET 框架中的许多类都提供了许多很方便的属性可以直接映射到 HttpContext 类中定义的属性.这种交叠有一个很好的例子就是 HttpAppl ...

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

    使用 HttpRequest 对象 HttpRequest 对象描述的是一个正在被处理的 HTTP 请求.下表列举了 HttpRequest 中的属性,它们提供了当前请求的相关信息(HttpReque ...

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

    使用特殊方法处理请求生命周期事件 为了在全局应用类中处理这些事件,我们会创建一个名称以 Application_ 开头,以事件名称结尾的方法,比如 Application_BeginRequest.举 ...

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

    不使用特殊方法来处理请求生命周期事件 HttpApplication 类是全局应用类的基类,定义了可以直接使用的一般 C# 事件.那么使用标准 C# 事件还是特殊方法那就是个人偏好的问题了,如果喜欢, ...

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

    ASP.NET 请求生命周期 全局应用类也可以用来跟踪每个独立请求的生命周期,包括请求从 ASP.NET 平台传递到 MVC 框架.ASP.NET 框架会创建一个定义在 Global.asax 文件中 ...

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

    使用 HttpResponse 对象 HttpResponse 对象是与 HttpRequest 对象相对应的,用来表示构建中的响应.它当中提供了方法和属性可供我们自定义响应,有一些在使用 MVC 视 ...

  8. Asp.net生命周期与Http协议

    Http协议,底层的东西还是不是特别熟悉,感觉要经过沉淀之后才能理解这些东西吧 1.Asp.net生命周期 Asp.net生命周期: 从发起请求开始,到IIS进行处理的全部过程,然后再到获取结果 当请 ...

  9. Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用

    一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...

随机推荐

  1. oracle 10g升级到11g

    Linux 上Oracle RAC 10g 升级到 Oracle RAC 11g 了解如何在 Oracle Enterprise Linux 5 上逐步将 Oracle RAC 10g 第 2 版升级 ...

  2. PLS-00201: 必须声明标识符 'UTL_FILE'

    解决办法: 用sysdba身份 把UTL_FILE包的执行权限给这个用户. 举例: 1.C:\Users\Anakin>sqlplus /nolog2.SQL> connect /as s ...

  3. Scala中的类和对象

    类的定义 使用class定义 类的字段 在类中使用var,val定义字段 类的方法 scala中,使用var定义字段默认提供setter和getter方法对应名称为 value_= 和value /* ...

  4. [改善Java代码]覆写变长方法也循规蹈矩

    建议6:覆写变长方法也循规蹈矩 在Java中,子类覆写父类中的方法很常见,这样做既可以修正Bug也可以提供扩展的业务功能支持,同时还符合开闭原则(Open-Closed Principle),我们来看 ...

  5. [未完成]关于POI的使用

    关于POI的使用关于POI的使用关于POI的使用关于POI的使用

  6. 【STL+模拟】UVa 506 - System Dependencies

    System Dependencies  Components of computer systems often have dependencies--other components that m ...

  7. Lombok(1.14.8) - @Synchronized

    @Synchronized @Synchronized,实现同步. package com.huey.lombok; import java.util.Date; import lombok.Sync ...

  8. 【Knockout】二、监控属性Observables

    MVVM和viewModel Knockout是建立在以下三大核心功能之上的: 监控属性和依赖跟踪(Observables and dependency tracking) 声明式绑定(Declara ...

  9. 【SQLServer】将Job运行结果发送电子邮件通知用户

    SQLServer2005/2008数据库邮件功能: 1. 启用数据库邮件功能:打开SQL Server 2005 外围应用配置器,选择“功能的外围应用配置器”,选择“数据库邮件”,勾选“启用数据库邮 ...

  10. 第二篇、为UITableViewCell 高度自适应加速 缓存cell的高度

    通过NSCache缓存已经算好的行高 @interface ZHCellHeightCalculator : NSObject //系统计算高度后缓存进cache -(void)setHeight:( ...