asp.net处理事件

从来不用也从来不研究这事件.但为了写那种CGI式的接口不得已研究一下.

环境  W10 VS2017

测试方法:写一个实现IHttpModule接口的类,在Init方法中加载所有事件然后打出日志,看看事件执行顺序.

模块接口类需要在IIS中打开"模块"->添加"模块"后使用.或者在webconfig里添加模块节点也行.

事件执行结果如下:

  • 0在 ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生。BeginRequest
  • 1 当安全模块建立用户标识时发生 AuthenticateRequest
  • 2 当安全模块已建立用户标识时发生。PostAuthenticateRequest
  • 3 当安全模块已验证用户授权时发生。AuthorizeRequest
  • 4 在当前请求的用户已获授权时发生。PostAuthorizeRequest
  • 5 在 ASP.NET 完成授权事件以使缓存模块从缓存中为请求提供服务后发生,从而绕过事件处理程序(例如某个页或 XML Web services)的执行。ResolveRequestCache
  • 6 在 ASP.NET 跳过当前事件处理程序的执行并允许缓存模块满足来自缓存的请求时发生。PostResolveRequestCache
  • 7 在选择了用来响应请求的处理程序时发生 MapRequestHandler
  • 8 在 ASP.NET 已将当前请求映射到相应的事件处理程序时发生。PostMapRequestHandler
  • 9 当 ASP.NET 获取与当前请求关联的当前状态(如会话状态)时发生。AcquireRequestState
  • 10 在已获得与当前请求关联的请求状态(例如会话状态)时发生。PostAcquireRequestState
  • 11 恰好在 ASP.NET 开始执行事件处理程序(例如,某页或某个 XML Web services)前发生。PreRequestHandlerExecute
  • 12 当引发未经处理的异常时发生 Error
  • 13 在 ASP.NET 事件处理程序(例如,某页或某个 XML Web service)执行完毕时发生。PostRequestHandlerExecute
  • 14 在 ASP.NET 执行完所有请求事件处理程序后发生。该事件将使状态模块保存当前状态数据。ReleaseRequestState
  • 15 在 ASP.NET 已完成所有请求事件处理程序的执行并且请求状态数据已存储时发生。PostReleaseRequestState
  • 16 当 ASP.NET 执行完事件处理程序以使缓存模块存储将用于从缓存为后续请求提供服务的响应时发生。UpdateRequestCache
  • 17 在 ASP.NET 完成缓存模块的更新并存储了用于从缓存中为后续请求提供服务的响应后,发生此事件。PostUpdateRequestCache
  • 18 恰好在 ASP.NET 为当前请求执行任何记录之前发生。LogRequest
  • 19 在 ASP.NET 处理完 System.Web.HttpApplication.LogRequest 事件的所有事件处理程序后发生。PostLogRequest
  • 20在 ASP.NET 响应请求时作为 HTTP 执行管线链中的最后一个事件发生。EndRequest
  • 21 恰好在 ASP.NET 向客户端发送 HTTP 标头之前发生。PreSendRequestHeaders
  • 22 恰好在 ASP.NET 向客户端发送内容之前发生。PreSendRequestContent

一共有25个事件,日志显示了23个.有2个未打出.

  Disposed // 在释放应用程序时发生.   ----也可以自己调用Dispose()方法来引发这个事件,最好在EndRequest事件里调用,调用之后应用程序对象就没有了.

  RequestCompleted// 当托管对象与已经释放的请求相关联时发生。  ----这个不知道怎么触发

为了让一个类的方法变成接口可以这样:(参考博客http://www.cnblogs.com/fish-li/archive/2011/09/05/2168073.html)

  1. 用IHttpModule模块: 在模块中动态调用这个类的方法.简单的讲就是根据URL地址找到类名和方法名,然后用"反射"调用它们,并且将上下文对象传给这方法.
  2. 用IHttpHandler处理: 方法同上.

  根据参考博客提出的建议,使用IHttpHandler方法好.这个问题我看了几遍博客才有些明白.

------疑惑在于一直想不清楚IHttpModule和IHttpHandler区别到底在哪里.为什么要提供这两接口.现在看来,需要从这管道处理事件的设计角度看,能找到原因.------

管道处理方式设计:

  既然设计处理事件,也就是说将一次HTTP请求的处理过程硬性规定为这些步骤,每个步骤用注册事件的方式来执行自定义操作.这些步骤制定的是否合理,需要问设计者.这些事件也会调整,以前版本ASP.NET并没有25个事件,好像是19个.这样看来,没有合理,只有不断调优.之前写贪吃蛇游戏,采用的是类似的方法,在蛇每移动一下这个时刻,分解为几个步骤,判断蛇的状态,然后执行相应代码.这样做有个好处就是容易扩展功能,比如要新加一个状态,只要找到合适的步骤,将方法注册到这步骤上就行了.当然,前提是这些步骤设计得"合理".

IHttpModule与IHttpHandler时机

   IHttpModule的作用是注册管道事件,"所有请求"都会被执行这个类里注册过的事件(这个可能是错的).而IHttpHandler是一个处理程序,它属于管道处理的其中一个环节.经过打印日志发现:    

在第11个事件之后,执行IHttpHandler  // (11 恰好在 ASP.NET 开始执行事件处理程序(例如,某页或某个 XML Web services)前发生。)PreRequestHandlerExecute

另外在第7个事件之后,执行IHttpHandlerFactory(这个用于指定使用哪个IHttpHandler,详见参考博客)  //  7 在选择了用来响应请求的处理程序时发生 MapRequestHandler

HttpApplication类管理事件处理

  HttpApplication类管理这些事件的运行,它有一个方法CompleteRequest();  /使 ASP.NET 跳过 HTTP 执行管线链中的所有事件和筛选并直接执行 EndRequest 事件

 如果在第一个事件,BeginRequest事件中调用这个方法.那么程序打印日志如下:

  • 0在 ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生。BeginRequest
  • 18 恰好在 ASP.NET 为当前请求执行任何记录之前发生。LogRequest
  • 19 在 ASP.NET 处理完 System.Web.HttpApplication.LogRequest 事件的所有事件处理程序后发生。PostLogRequest
  • 20在 ASP.NET 响应请求时作为 HTTP 执行管线链中的最后一个事件发生。EndRequest
  • 21 恰好在 ASP.NET 向客户端发送 HTTP 标头之前发生。PreSendRequestHeaders
  • 22 恰好在 ASP.NET 向客户端发送内容之前发生。PreSendRequestContent

  第1个和最后5个事件触发了,而IHttpHandler 需要在第11个事件后触发,所以没机会,就没执行.这说明IHttpHandler是管道过程中的其中一个环节.

  管道事件可以跳过而不执行,那么如果是充分利用ASP.NET管道事件机制的系统,它的很多代码都在注册在各事件步骤,那么随意跳过肯定不行.因为不能保证其它模块注册的事件有机会执行.

如果完全不使用这些事件也不使用这些模块,只是"为了让一个类的方法变成接口",那么,事件可以一个也不注册.模块可以不加载.但处理程序IHttpHandler一定要的.

模块和处理程序映射设置(关于IIS模块详见:      https://docs.microsoft.com/en-us/iis/get-started/introduction-to-iis/introduction-to-iis-architecture          )

  在IIS中新建一个网站后,(集成模式.NET4.0).已经加载了很多模块和处理程序映射了.可以删除不需要的模块(如果是继承的,删除不掉,需要在IIS节点上打开"模块",然后选中模块,点解除锁定.再到站点中就可以删除了)

  重要的模块:

  StaticFileModule(默认,本机,继承)

    // 用于处理静态文件,html,js,css.等等 如果不加的话,静态文件访问不了.

  DirectoryListingModule(默认,本机,继承)

    // 目录浏览功能,如果不加将,允许目录浏览权限的地方看不到目录列表.现在几乎没人浏览网站下的目录.除非是个FTP

  DefaultDocumentModule(默认,本机,继承)

    // 默认文档,例如http://www.xx/home 这样的URL会显示默认的index.htm(如果设定这个默认文档的话).如果不加,则没这功能.必须输入全的 http://www.xx/home/index.html

  AnonymousAuthenticationModule(默认,本机,继承)

    // 匿名验证.如果不加,网页打不开,提示没权限401错误.并且会触发第2个管道事件(当安全模块已建立用户标识时发生 AuthenticateRequest)后,马上触发 18-22事件.效果如同调用了 CompleteRequest()

  重要的处理程序映射:

  StaticFile 请求路径: *  模块: StaticFileModule,DefaultDocumentModule,DirectoryListingModule 权限:读取,脚本 请求限制:读取

    // 如果没有这个映射:静态文件访问不了.提示找不到404

模块和处理程序的关系:

  究竟处理程序和模块间有没关系?

  A. 处理程序映射:(在IIS功能,"处理程序映射"双击打开)可以添加几种

    1."添加托管处理程序",这种会设定"请求路径","类型",请求路径可以是*,*.ext,*.ashx,还可有目录如/api/*.总之是一个路径规则,"类型"就是这个处理程序的类名(带命名空间),请求限制还可设定如何调用这个处理程序,一般不用勾选映射选项.设定好之后,凡是符合这种路径规则的请求,都会执行这个处理程序.程序类必是实现了IHttpHandler接口的.

    2."添加模块映射",这种会设定"请求路径",模块,在模块下拉列表中只有本机安装好的模块,如果要自己模块则需要在IIS根上双击模块->配置本机模块->注册这个地方添加.然后在站点的"模块"功能中添加这个本机模块后,下拉列表里才有.(我使用C#写的实现IHttpModule接口的类编译成DLL后,注册.发现没有效果.不知道是什么原因).

  以上两种设定,感觉如下,IHttpModule和IHttpHandler都能处理请求,并且可以让IHttpHandler处理程序负责某一类路径规则的所有请求(1),也可以为另一种路径规则的请求指定用哪些模块处理(2).

  那么也就是说模块也不再是针对所有请求的了,那么这个模块中注册的事件,也可以只是针对某一类请求的.(这可能是个误解,可能本机模块和托管模块有很大区别)

  B.模块:(在IIS功能,"模块")

    添加指托管模块(实现IHttpModule接口的),有一个选项"仅针对向ASP.NET应用程序或托管处理程序发出的请求调用".选中和不选中时有区别.如果选了,那么在请求静态文件时,发现模块并不执行,而请求某个处理程序时,模块才执行.如果没有选择,那么处理静态文件时,它也执行了.这表明模块注册的事件是针对所有请求都有效的.

    这个选项在于解决一个明显问题,就是"如果说模块是针对所有请求的"那么请求静态文件时,这个模块的功能也会执行,但是大多数情况下,静态文件就是直接发向客户端了,并不需要去执行模块里的事件.不需要经过管道处理.

  I.上述情况或许表明,托管模块或者处理程序在实际上都是针对某种请求而设计,并不需要一种接管所有请求的模块或者处理程序.至少静态文件和动态文件的处理是不同的,StaticFile这个模块映射使用的路径是*,表明它接管所有请求,并且使用DefaultDocumentModule,DirectoryListingModule,StaticFileModule这三个模块处理这些请求.那么其它路径规则应该是在它之前执行,如果都找不到才丢给它当做静态文件处理(猜测的).

  II.小结:

    托管模块IHttpModule注册的事件是针对所有请求的,但在添加时,可以选择只针对托管请求(或者说是指明了处理程序的请求).它的作用在于注意各种事件,并不具体处理请求和返回结果.(虽然也可以)

    处理程序IHttpHandler是若干事件中的一个步骤,是在11步之后执行的.它的重要工作是返回一个处理结果.并不需要关心自己在处理事件中的位置

  III.如果完全不使用这套处理管道机制,那么也就没必要用ASP.NET了.可以用System.Net.HttpListener这个类写一个监听程序然后挂上自己的C#程序.

为了让一个类的方法变成接口,可以:

  定制一个网站,只加载必要的模块和处理程序映射,然后将自己的类库项目,再弄一个web.config(这个可以方便配置模块与映射,而不需要在IIS控制台上配置)放到这网站目录中,执行程序放bin.web.config放根目录 ,这样就可行.

------------------------------------随时修正和补充-----------------------------------

原文地址:https://www.cnblogs.com/mirrortom/p/8401732.html

时间: 2024-11-08 02:15:32

asp.net处理事件的相关文章

大家好

http://www.yugaopian.com/people/259723 http://www.yugaopian.com/people/259744 http://www.yugaopian.com/people/259783 http://www.yugaopian.com/people/259824 http://www.yugaopian.com/people/259839 http://www.yugaopian.com/people/259933 http://www.yugao

阿哥吗卡怪每次哦阿哥看啦过啦嘎开吃麻辣个啊蓝光

http://www.xx186.com/web/web_kpic.asp?id=156613http://www.xx186.com/web/web_kpic.asp?id=156608http://www.xx186.com/web/web_kpic.asp?id=156605http://www.xx186.com/web/web_kpic.asp?id=156602http://www.xx186.com/web/web_kpic.asp?id=156600http://www.xx18

风格更家霍建华

http://www.9ku.com/fuyin/daogaoo.asp?dgid=119864http://www.9ku.com/fuyin/daogaoo.asp?dgid=119867http://www.9ku.com/fuyin/daogaoo.asp?dgid=119876http://www.9ku.com/fuyin/daogaoo.asp?dgid=119879http://www.9ku.com/fuyin/daogaoo.asp?dgid=119883http://www

,了可美军以本合同个v分

http://shike.gaotie.cn/zhan.asp?zhan=%A1%FE%CE%F7%B0%B2%B8%B4%B7%BD%B5%D8%B7%D2%C5%B5%F5%A5%C6%AC%C4%C4%C0%EF%C2%F2Q%A3%BA%A3%B1%A3%B1%A3%B2%A3%B7%A3%B4%A3%B0%A3%B1%A3%B1%A3%B7%A3%B5%A1%F4 http://shike.gaotie.cn/zhan.asp?zhan=%A8%7D%CD%AD%B4%A8%B8%B4

[Architect] ABP(现代ASP.NET样板开发框架)(2) 分层架构

本节目录 介绍 Domain Layer Application Layer Infrastructure Layer Web Layer SPA & MPA frameworks/libraries 其他 介绍 为了减少复杂性和提高代码的可重用性,采用分层架构是一种被广泛接受的技术. ABP遵循Domain Driven Design,在DDD中,会有4个基础分层. Presentation(展现层): 引用 Application Layer ,提供用户界面. Application(应用层

ASP.NET数据控件

数据服务器控件就是能够显示数据的控件,与那些简单格式的列表控件不同,这些控件不但提供显示数据的丰富界面(可以显示多行多列数据并根据用户定义来显示),还提供了修改.删除和插入数据的接口. ASP.NET 4.0提供的主要数据服务器控件: 1.GridView:是一个全方位的网格控件,能够显示一整张表的数据,它是ASP.NET中最为重要的数据控件. 2.DetailsView :是用来一次显示一条记录. 3.FormView :也是用来一次显示一条记录,与DetailsView不同的是,FormVi

Asp.net管道 (第二篇)

从请求进入ASP.NET工作者进程,直至它到达最终的处理程序之前要经过一系列的步骤和过程,这个步骤和过程称为ASP.NET处理管道. Asp.net的处理管道流程如下: 语言描述如下: Asp.net处理管道的第一步是创建HttpWorkerRequest对象,它包含于当前请求有关的所有信息. HttpWorkerRequest把请求传递给HttpRuntime类的静态ProcessRequest方法.HttpRuntime首先要做的事是创建HttpContext对象,并用HttpWorkerR

如鹏网学习笔记(十四)ASP.NET

Asp.net笔记 一.Socket类 进行网络编程的类,可以在两台计算机之间进行网络通讯 过程: 向服务器发送指令: GET /index.html HTTP/1.1 Host:127.0.0.1:8080 回车空行 二.浏览器是什么 浏览器就是一个Socket网络客户端,帮助用户请求网站服务器上的内容并且将返回的内容渲染为图形化内容 浏览器的过程: 用户在浏览器输入网址,浏览器向DNS服务器发出Socket请求, 服务器把请求的内容返回给浏览器, 浏览器将内容进行解析并渲染绘制成页面展现,

ASP.NET 学习的总结

应用程序域 使用.Net建立的可执行程序*.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.应用程序域是.Net引入的一个新概念,它比进程所占用的资源要少,可以被看做是一个轻量级的进程.一个应用程序域可以有多个线程,一个线程也可以穿梭于多个应用程序域. 那为什么会出现应用程序域呢?根据它的名字"域"我们可能会联想到域名,其实差不多就是这个概念了,ASP.NET通过这个应用程序域,主要的功能就是进行隔离. 这样在不一个网站死掉的情况下,部署在IIS上的其