不使用特殊方法来处理请求生命周期事件

HttpApplication 类是全局应用类的基类,定义了可以直接使用的一般 C# 事件。那么使用标准 C# 事件还是特殊方法那就是个人偏好的问题了,如果喜欢,也可以将这两种方式混合起来使用。

  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. BeginRequest += (src, args) => RecordEvent("BeginRequest");
  15. AuthenticateRequest += (src, args) => RecordEvent("AuthenticateRequest");
  16. PostAuthenticateRequest += (src, args) => RecordEvent("PostAuthenticateRequest");
  17. }
  18.  
  19. protected void Application_Start()
  20. {
  21. AreaRegistration.RegisterAllAreas();
  22. RouteConfig.RegisterRoutes(RouteTable.Routes);
  23. }
  24.  
  25. private void RecordEvent(string name)
  26. {
  27. List<string> eventList = Application["events"] as List<string>;
  28. if (eventList == null)
  29. {
  30. Application["events"] = eventList = new List<string>();
  31. }
  32. eventList.Add(name);
  33. }
  34. }
  35. }

我们已经在 MvcApplication 类中添加了一个构造器,并为其中三个请求生命周期事件建立事件处理器。而这三个事件我都使用了 lambda 表达式来调用 RecordEvent 方法,存储事件的名称供 controller 来读取,与之前的例子一样。

提示:没有标准的 C# 事件来代替 Application_Start 和 Application_End 方法。我们仅能够通过特殊方法来接收这两个通知。

使用单个方法处理多个事件

如果我们想要使用一个方法来处理多个生命周期事件而不依赖 lambda 表达式,那么 System.Web.HttpContext 类中定义的两个属性可以帮助我们。HttpContext 类中提供了当前请求和应用状态的详细信息,我们会在后面详细介绍。然而目前,我们只会介绍与处理生命周期事件的两个属性。

名称 描述
CurrentNotification 这个属性会使用 System.Web.RequestNotification 枚举中的值来指示当前应用事件。
IsPostNotification 如果 CurrentNotification 属性返回的当前应用事件名称是 Post<Name> 的变体,那么这个属性就会返回 true。

这两个属性有一点奇怪,因为两者都需要计算出哪个事件正在被处理。CurrentNotification 属性返回一个 RequestNotification 枚举值,当中定义了 HttpApplication 事件的子集。IsPostNotification 属性值是根据当前触发的事件是否是一个像 AcquireRequestState 的事件还是与其配对的 PostAcquireRequestState 事件计算出来的。在 HttpApplication 类中,可以通过 Context 属性获取到 HttpContext 对象。

  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. BeginRequest += RecordEvent;
  15. AuthenticateRequest += RecordEvent;
  16. PostAuthenticateRequest += RecordEvent;
  17. }
  18.  
  19. protected void Application_Start()
  20. {
  21. AreaRegistration.RegisterAllAreas();
  22. RouteConfig.RegisterRoutes(RouteTable.Routes);
  23. }
  24.  
  25. private void RecordEvent(object src, EventArgs args)
  26. {
  27. List<string> eventList = Application["events"] as List<string>;
  28. if (eventList == null)
  29. {
  30. Application["events"] = eventList = new List<string>();
  31. }
  32. string name = Context.CurrentNotification.ToString();
  33. if (Context.IsPostNotification)
  34. {
  35. name = "Post" + name;
  36. }
  37. eventList.Add(name);
  38. }
  39. }
  40. }

我改变了 RecordEvent 方法的签名,因此采用了标准的事件处理器签名:一个对象代表的是事件的源,EventArgs 对象描述的就是事件。我没有使用这两个参数提供的值,相反,我使用了 Context.CurrentNotification 属性和 Context.IsPostNotification 属性提供的相关信息。

我不明白微软为什么以这样的一个方式来实现事件,但是如果你不想使用特殊方法或者 lambda 表达式的话,那你就必须使用这种方式。注意到,在上面的代码中,我在 Context.CurrentNotification 属性上使用了 ToString 方法,这是必须的,因为 CurrentNotification 属性返回的是一个 System.Web.RequestNotification 枚举值。详见下表:

表 1 – RequestNotification 枚举值

描述
BeginRequest 对应到 BeginRequest 事件
AuthenticateRequest 对应到 AuthenticateRequest 和 PostAuthenticateRequest 事件
AuthorizeRequest 对应到 AuthorizeRequest 事件
ResolveRequestCache 对应到 ResolveRequestCache 和 PostResolveRequestCache 事件
MapRequestHandler 对应到 MapRequestHandler和 PostMapRequestHandler 事件
AcquireRequestState 对应到 AcquireRequestState 和 PostRequestState 事件
PreExecuteRequestHandler 对应到 PreExecuteRequestHandler 事件
ExecuteRequestHandler 对应到 ExecuteRequestHandler 事件
ReleaseRequestState 对应到 ReleaseRequestState 和 PostReleaseRequestState 事件
UpdateRequestCache 对应到 UpdateRequestCahce 事件
LogRequest 对应到 LogRequest 事件
EndRequest 对应到 EndRequest 事件
SendResponse 指示响应正在被发送——不完全对应到 PreSendRequestHeaders 和 PreSendRequestContent 事件

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

[译] ASP.NET 生命周期 – ASP.NET 请求生命周期(四)的更多相关文章

  1. C# MVC 5 - 生命周期(应用程序生命周期&请求生命周期)

    本文是根据网上的文章总结的. 1.介绍 本文讨论ASP.Net MVC框架MVC的请求生命周期. MVC有两个生命周期,一为应用程序生命周期,二为请求生命周期. 2.应用程序生命周期 应用程序生命周期 ...

  2. $Django orm增删改字段、建表 ,单表增删改查,Django请求生命周期

    1 orm介绍  ORM是什么   ORM 是 python编程语言后端web框架 Django的核心思想,“Object Relational Mapping”,即对象-关系映射,简称ORM.  一 ...

  3. django请求生命周期流程与路由层相关知识

    目录 请求生命周期流程图 路由层之路由匹配 无名有名分组 反向解析 无名有名分组反向解析 路由分发 名称空间 请求生命周期流程图 django请求生命周期流程图 路由层之路由匹配 我们都知道,路由层是 ...

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

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

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

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

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

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

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

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

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

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

  9. 详解ASP.NET MVC的请求生命周期

    本文的目的旨在详细描述asp.net mvc请求从开始到结束的每一个过程. 我希望能理解在浏览器输入url并敲击回车来请求一个asp.net mvc网站的页面之后发生的任何事情. 为什么需要关心这些? ...

随机推荐

  1. 修改Linux网卡由eth1变成eth0

    正常来说,Linux在识别网卡时第一张会是eth0,第二张才是eth1.有时候我们使用虚拟机克隆技术后网卡的信息就会改变,新克隆出来的虚拟主机网卡名字可能变为eth1.无论我们怎么修改都无法改变,这就 ...

  2. [改善Java代码]断言绝对不是鸡肋

    建议19: 断言绝对不是鸡肋 在防御式编程中经常会用断言(Assertion)对参数和环境做出判断,避免程序因不当的输入或错误的环境而产生逻辑异常,断言在很多语言中都存在,C.C++.Python都有 ...

  3. javascript基础知识--函数定义

    函数声明式 function funname( 参数 ){ ...执行的代码 } 声明式的函数并不会马上执行,需要我们调用才会执行:funname(); * 分号是用来分隔可执行JavaScript语 ...

  4. Linux 命令 - watch: 反复执行命令,全屏显示输出

    watch 命令周期性地执行命令,全屏显示输出.可以通过 watch 命令反复执行某一程序来监视它的输出变化. 命令格式 watch [-dhvt] [-n <seconds>] [--d ...

  5. Jquery EasyUI的datagrid页脚footer使用及数据统计

    最近做一个统计类的项目中遇到datagrid数据显示页脚footer合计的问题,对于构造统计结果数据格式,是在程序端构造一个{"rows":[],"total" ...

  6. Unity3d导入工程出现错误“Creating unique file”的解决方法

    Unity3d导入工程出现错误“Creating unique file:creating file Temp/tempFile failed.Please ensure there is enoug ...

  7. HTTP相关知识 --转载

    转载之,言简意赅

  8. zookeeper启动报错(数据目录权限不对)

    zookeeper启动报错日志: 2016-11-16 11:19:43,880 [myid:3] - INFO [WorkerReceiver[myid=3]:FastLeaderElection@ ...

  9. 如何设置Win7系统中的上帝模式GodMode(转载)

    如何设置Win7系统中的上帝模式GodMode(转载) NT6系统中隐藏了一个秘密的“GodMode”,字面上译为“上帝模式”.God Mode其实就是一个简单的文件夹窗口,但包含了几乎所有系统的设置 ...

  10. html保留字符详解

    本文由 www.169it.com 搜集整理 1. 注释 HTML中的注释和其它语言注释作用相似,都是为了方便阅读和调试代码.当浏览器遇到注释时会自动忽略注释内容.HTML的注释格式多行和单行注释都用 ...