当前位置: 首页 > 编程日记 > 正文

[译] 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 对象非常困难,我们可以看一下下面的代码:

 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 选译]

相关文章:

变得非常不vb

数组-136. 只出现一次的数字题目描述题目样例Java方法&#xff1a;位运算算法思路代码复杂度题目描述 给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 题目样例 示例1&#xff1a; 输入: […

分析PHP中单双引号的误区和双引号小隐患

2019独角兽企业重金招聘Python工程师标准>>> 1、一般情况下两者是通用的.但如果双引号内写的是变量就会执行解析操作,而单引号则不解析&#xff0c;这个怎么说&#xff1f;还是举个例子吧。 这下看明白了吧&#xff01; 2、执行效率不一样&#xff0c;单引号的执行速…

javascript(js)的小数点乘法除法问题

一、用js计算12.32 * 7 结果是多少&#xff1f;答案&#xff1a;86.24000000000001为什么会出现这种问题&#xff1f;怎么解决&#xff1f;js在处理小数的乘除法的时候有一个bug&#xff0c;解决的方法可以是&#xff1a;将小数变为整数来处理。以上的计算可以改为&#xff1a…

sDVD消防大队

数组-136. 只出现一次的数字题目描述题目样例Java方法&#xff1a;位运算算法思路代码复杂度题目描述 给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 题目样例 示例1&#xff1a; 输入: […

WPF的二维绘图(二)——几何图形Geometry

在WPF的DrawingContext对象中&#xff0c;提供了基本的绘制椭圆和矩形的API&#xff1a;DrawEllipse和DrawRectangle。但是&#xff0c;这些是远远不够用的&#xff0c;我们在日常应用中&#xff0c;更多的是使用DrawGeometry函数&#xff0c;它可以绘制更多复杂的几何图形&…

定期删除各子文件下数据

最近遇到一个客户有这样一个需求&#xff0c;需要在每日自动删除各用户文件夹下的数据而不删除根文件夹和每个用户父文件夹 Register-ScheduledJob -Name Remove-InternetDataFiles -ScriptBlock {$root "E:\Internet-Data"$dirs Get-ChildItem $root -Directoryfo…

PHP使用BC Math 函数处理浮点运算问题

BC Math 函数 http://cn.php.net/manual/zh/ref.bc.php做小数的相加减问题是&#xff0c;出现了浮点运算不准的情况&#xff0c;看来都说解释型语言对于浮点运算都会有问题的说法是真的。首先看一段代码: <?php$a 0.1;$b 0.7;var_dump(($a $b) 0.8); 打印出来的值居然为…

【重建】从FJOI2016一试谈起

2016.2.21 我是湖建的sb蒟蒻OIer FOIWCFJOI2016 体验性的旅途&#xff0c;新生 其实是刚刚找回密码闲的没事干 前排膜FZSZ各位学长 ORZ 闫神 ORZ 吴大爷 ORZ 汪巨 ORZ 邵司机 ORZ 方老师ORZ dxy zkp zzy 湖建省选一试被虐。不知道明年这个时候会有什么改变 总而言之&#xff…

是否正常正常是

数组-136. 只出现一次的数字题目描述题目样例Java方法&#xff1a;位运算算法思路代码复杂度题目描述 给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 题目样例 示例1&#xff1a; 输入: […

pkg mysql 在macOS 上的管理

为什么80%的码农都做不了架构师&#xff1f;>>> 使用pkg安装后&#xff0c;在设置中启停&#xff0c;通过ps -ef|grep mysql查看进程的命令行即可看到各配置位置。 转载于:https://my.oschina.net/fox99/blog/1931674

PHP autoload 函数

(1) autoload机制概述 在使用PHP的OO模式开发系统时&#xff0c;通常大家习惯上将每个类的实现都存放在一个单独的文件里&#xff0c;这样会很容易实现对类进行复用&#xff0c;同时将来维护时也很便利。这也是OO设计的基本思想之一。在PHP5之前&#xff0c;如果需要使用一个…

sql按条件进行批量查询或update的关键字in

2019独角兽企业重金招聘Python工程师标准>>> SELECT t1.field1,t1.field2,t1.field3 from t1 where t1.pid in (select fid from t2 where t2.ch%123456%) 再看这段代码&#xff0c; select t.* from mefinance.me_customer_info t where t.id in (3285,4241,4243,4…

为什么很努力进步却不明显

今天有个玩的不错的同事问了我一个问题&#xff1a;他说我今年在努力学习测试方法&#xff0c;自动化测试等等&#xff0c;也写了不少测试用例&#xff0c;但总体感觉好像没有什么进步啊&#xff1f;他想不明白这是什么原因。其实当我遇到这个问题的时候&#xff0c;我也想了一…

spl_autoload_register与autoload区别

spl_autoload_register(PHP 5 > 5.1.2)spl_autoload_register — 注册__autoload()函数说明bool spl_autoload_register ([ callback $autoload_function ] )将函数注册到SPL __autoload函数栈中。如果该栈中的函数尚未激活&#xff0c;则激活它们。如果在你的程序中已经实现…

宣传部vv从v

数组-136. 只出现一次的数字题目描述题目样例Java方法&#xff1a;位运算算法思路代码复杂度题目描述 给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 题目样例 示例1&#xff1a; 输入: […

自动配置IPv4问题

对于 Windows &#xff0c; 配置 IP&#xff0c;如&#xff1a; 192.168.1.101&#xff0c; 如果这个 IP 已经在局域网内存在&#xff0c;那么将会提示局域网内已经存在该 IP。 而这个时候&#xff0c;Windows 7 将产生一个 “自动配置IPv4地址”&#xff0c;如&#xff1a;169…

营销自动化为什么能吸引企业的喜欢?它有何魅力?

在一次营销峰会上&#xff0c;我们听到这样一个令人惊讶的描述&#xff1a;“到2020年底&#xff0c;将会有85%的客户与企业的关系在没有人际互动的情况下进行管理。”虽然这听起来可能有点超前&#xff0c;但从营销的角度来看&#xff0c;“未来”已来。这个“未来”就是我们所…

php base64解码图片 base64加密图片还原

<?php//文件名:base64.php $data"/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2MBERISGBUYLxoaL2NCOEJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY//AABEIADIA…

python mysql

2019独角兽企业重金招聘Python工程师标准>>> python实践3&#xff1a;cursor() — 数据库连接操作 (2012-05-07 11:00:40) 转载▼ 标签&#xff1a; itpython 操作数据库&#xff0c;要安装一个Python和数据库交互的包MySQL-python-1.2.2.win32-py2.5.exe&#xff0…

程序员效率低下的35个坏习惯

优秀程序员与平庸程序员的最终差别其实是习惯&#xff0c;避开那些让自己低效的坏习惯是程序员让自己变优秀的有效途径。 1.总是说“一会弄好”&#xff0c;但从来不兑现。&#xff08;缺乏任务管理和时间管理能力&#xff09;2坚持所谓的高效、优雅的“一行代码流”&#xff0…

PHP处理Oracle的CLOB

1. 写入数据在使用PDO的预处理方法时&#xff0c;如果使用bindParam()等而不指定字段的数据类型或使用execute()&#xff0c;PDO都会默认为string类型&#xff0c;并且限定一个默认长度 所以在存clob类型字段时必须使用bindParam()或bindValue()等&#xff0c;并指定字符…

c# 元组Tuple

Tuple类型像一个口袋&#xff0c;在出门前可以把所需的任何东西一股脑地放在里面。您可以将钥匙、驾驶证、便笺簿和钢笔放在口袋里&#xff0c;您的口袋是存放各种东西的收集箱。C# 4.0引入的一个新特性 Tuple类型与口袋类似&#xff0c;它可以存放不同类型的对象。CodeProject…

KVM之安装虚拟机

一、KVM安装&#xff1a;环境要求&#xff1a;1、如果是物理服务器&#xff0c;需要在BIOS中打开虚拟化VirtualizationTechnology一般的服务器默认是打开这个功能的。 2、如果是用VMware Workstation做实验&#xff0c;建立的虚拟机的CPU要勾选虚拟化功能&#xff0c;这样虚拟机…

使用 Strace 调试工具

strace是Linux环境下的一款程序调试工具&#xff0c;用来监察一个应用程序所使用的系统呼叫及它所接收的系统信息。 strace是一个有用的小工具&#xff0c;它可以通过跟踪系统调用来让你知道一个程序在后台所做的事情。Strace是一个基础的调试工具&#xff0c;在大多数Linux系 …

java——网络知识积累

1.获得局域网的所有主机ip地址 ping ip 等待每次回复的超时时间&#xff1a; -w 280 要发送的回显请求数&#xff1a;-n 1 Process processRuntime.getRuntime().exec("ping "); process.getInputStream()----InputStreamReader()----BufferReader in…

卸载v吧v字典序

数组-136. 只出现一次的数字题目描述题目样例Java方法&#xff1a;位运算算法思路代码复杂度题目描述 给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 题目样例 示例1&#xff1a; 输入: […

《JavaScript高级程序设计(第3版)》教程大纲

词条 《JavaScript高级程序设计》是2006年人民邮电出版社出版的图书&#xff0c;作者是(美)(Nicholas C.Zakas)扎卡斯。本书适合有一定编程经验的开发人员阅读&#xff0c;也可作为高校相关专业课程的教材。 献给搬砖人士&#xff0c;求职人士很不错的基础扎实笔记 前四章 js诞…

鸡肋的PHP单例模式

单例模式的要点有三个&#xff1a;一是某个类只能有一个实例&#xff1b;二是它必须自行创建这个实例&#xff1b;三是它必须自行向整个系统提供这个实例。<?php /* 单例模式举例,其要点如下: * * 1. $_instance 必须声明为静态的私有变量 * 2. 构造函数和克隆函数必须声明…

彻底理解js中this

相关博文&#xff1a;http://blog.csdn.net/libin_1/article/details/49996815彻底理解js中this的指向&#xff0c;不必硬背。 首先必须要说的是&#xff0c;this的指向在函数定义的时候是确定不了的&#xff0c;只有函数执行的时候才能确定this到底指向谁&#xff0c;实际上t…

cvsdfgdfdf

数组-136. 只出现一次的数字题目描述题目样例Java方法&#xff1a;位运算算法思路代码复杂度题目描述 给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 题目样例 示例1&#xff1a; 输入: […