IHttpHandler的那些事
写在前面
从上家公司离职,在家休息,闲着无聊,觉得还是有必要将IHttpHanlder的内容,做一个总结。发现在写demo的过程中,总觉得有点生疏了,项目中很少使用自定义的类来实现该接口。当然,一般处理程序除外。
IHttpHandler
在IHttpModule这篇文章中,有一个asp.net生命周期的简图。忘记的可以,翻到那篇文章,再熟悉一下。
当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。
HttpHandler是一个HTTP请求的真正处理中心,也正是在这个HttpHandler容器中,ASP.NET Framework才真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。
IHttpHandler定义了如果要实现一个HTTP请求的处理所必需实现的一些系统约定。HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。
当一个HTTP请求经同HttpModule容器传递到HttpHandler容器中时,ASP.NET Framework会调用HttpHandler的ProcessRequest成员方法来对这个HTTP请求进行真正的处理。以一个ASPX页面为例,正是在这里一个ASPX页面才被系统处理解析,并将处理完成的结果继续经由HttpModule传递下去,直至到达客户端。
对于ASPX页面,ASP.NET Framework在默认情况下是交给System.Web.UI.PageHandlerFactory这个HttpHandlerFactory来处理的。所谓一个HttpHandlerFactory,所谓一个HttpHandlerFactory,是指当一个HTTP请求到达这个HttpHandler Factory时,HttpHandlerFactory会提供出一个HttpHandler容器,交由这个HttpHandler容器来处理这个HTTP请求。
一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。
自定义一个处理请求的类
通过实现IHttpHandler接口可以创建自定义HTTP处理程序,该接口只包含两个方法。通过调用IsReusable,IHttpHandlerFactory可以查询处理程序以确定是否可以使用同一实例为多个请求提供服务。ProcessRequest方法将HttpContext实例用作参数,这使它能够访问Request和Response内部对象。在一个HttpHandler容器中如果需要访问Session,必须实现IRequiresSessionState接口,这只是一个标记接口,没有任何方法。
using System.Web;
using System.Web.SessionState;
namespace MyHttpHandler
{
/// <summary>
/// 自定义HttpHanlder
/// </summary>
public class MyHttpHandler:IHttpHandler,IRequiresSessionState
{
public bool IsReusable
{
get { return true; }
} public void ProcessRequest(HttpContext context)
{
context.Session["user"]="wolfy";
context.Response.Write(context.Session["user"].ToString());
context.Response.Write("httphandler");
}
}
}
在web.config中注册自定义的HttpHanlder
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" /> </system.web>
<system.webServer>
<handlers>
<add name="yhandler" path="*.aspx" verb="*" type="MyHttpHandler.MyHttpHandler,MyHttpHandler"/>
</handlers>
</system.webServer>
</configuration>
name:可以随意
path:指定请求哪些页面使用该自定义的HtppHanlder,支持通配符,如上例中的*.aspx.
type:类的全名称(命名空间+类名),程序集名称。
浏览aspx页面
IHttpHanlder工厂
ASP.NET Framework实际不直接将相关的页面资源HTTP请求定位到一个其内部默认的IHttpHandler容器之上,而定位到了其内部默认的IHttpHandler工厂上。IHttpHandler工厂的作用是对IHttpHandler容器进行调度和管理。
IHttpHandlerFactory接口包含两个方法。GetHandler返回实现IHttpHandler接口的类的实例,ReleaseHandler使工厂可以重用现有的处理程序实例。
namespace MyHttpHandler
{
/// <summary>
/// handler处理工厂
/// </summary>
public class HandlerFactory : IHttpHandlerFactory
{
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
PageHandlerFactory factory = (PageHandlerFactory)Activator.CreateInstance(typeof(PageHandlerFactory), true);
IHttpHandler handler = factory.GetHandler(context, requestType, url, pathTranslated);
Page page = handler as Page;
if (page != null)
{
page.Init += new EventHandler(page_Init);
}
return handler;
} private void page_Init(object sender, EventArgs e)
{
HttpContext.Current.Response.Write("IHttpHandlerFactory");
} public void ReleaseHandler(IHttpHandler handler)
{ }
}
}
在web.config中注册工厂
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" /> </system.web>
<system.webServer>
<handlers>
<!--<add name="yhandler" path="*.aspx" verb="*" type="MyHttpHandler.MyHttpHandler,MyHttpHandler"/>-->
<add name="handler1" path="*.aspx" verb="*" type="MyHttpHandler.HandlerFactory,MyHttpHandler"/>
</handlers>
</system.webServer>
</configuration>
浏览
这种方式,可以实现统一验证,在page_init方法中,判断session,判断用户是否登陆了。
总结
通过实现IHttpHandler接口,可以对请求做特殊的处理,比如防盗链的实现,验证码的实现方式等。
参考文章
一点一点学ASP.NET之基础概念——HttpHandler
IHttpHandler的那些事的更多相关文章
- IHttpHandler的学习(1)
IHttpHandler的那些事 今晚看了一晚上的IHttpHAndler的知识, 在自定义了Httphandler后,在配置webconfig里配置也是个技术活,什么集成模式,什么asp管道什么的: ...
- 准备.Net转前端开发-WPF界面框架那些事,搭建基础框架
题外话 最近都没怎么写博客,主要是最近在看WPF方面的书<wpf-4-unleashed.pdf>,挑了比较重要的几个章节学习了下WPF基础技术.另外,也把这本书推荐给目前正在从事WPF开 ...
- 关于Web Worker你必须知道的7件事
介绍 通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程.Web Worker可以提高应用的总体性能,并且提升用户体验.如果你想在自己的Web应用中 ...
- IHttpModule与IHttpHandler的区别整理
IHttpModule与IHttpHandler的区别整理1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行 ...
- NET那点不为人知的事
ASP.NET那点不为人知的事(一) 我们上网时,在浏览器地址输入网址:Http://www.cnblogs.com,按下回车,一张网页就呈现在我们眼前.这究竟发生了什么?对于一名优秀的Progr ...
- ASP.NET那点不为人知的事(一)
http://www.cnblogs.com/OceanEyes/archive/2012/08/13/aspnetEssential-1.html#_label0 我们上网时,在浏览器地址输入网址: ...
- HTTP请求处理流程、IHttphandler、IHttpModule
一.ASP.NET处理管道 Asp.net处理管道的第一步是创建HttpWorkerRequest对象,它包含于当前请求有关的所有信息. HttpWorkerRequest把请求传递给HttpRunt ...
- 【腾讯Bugly干货分享】H5 视频直播那些事
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...
- CSharpGL(31)[译]OpenGL渲染管道那些事
CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...
随机推荐
- MariaDB 主从复制
MySQL Replication:NySQL复制,MySQL的复制默认为异步工作模式 mysql的复制功能是mysql内置的,装上它之后就具备了这个功能,而mysql复制是mysql实现大规模 ...
- Java常量定义需要注意的两点
在任何开发语言中,都需要定义常量.在Java开发语言平台中也不例外.不过在Java常量定义的时候,跟其他语言有所不同.其有自己的特色.在这篇文章中,主要针对Java语言中定义常量的注意事项进行解析,帮 ...
- Time Step Too Small in Multisim
http://digital.ni.com/public.nsf/allkb/4B99B2CD6C0C3B6A86257205005D58E0 Error: Time Step Too Small i ...
- C#:让您知道您的方法是被何“人”调用
我们要在DisabledObsoleteMethod函数里限制具有“Obsolete”属性的方法调用,我们如何去做呢?在.Net中提供了一个"StackFrame"类用于表示当前线 ...
- 使用 JMeter 完成常用的压力测试
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- Ext表格控件
表格控件其实也就是帮我们完成了数据的填充工作而已,具体的数据源.要显示的列,列的定制.数据源中的哪条数据显示在哪个列中等属性还是需要我们自己手动配置的,所以我们分下面几步来完成网格控件的数据绑定: 1 ...
- 黑马day16 jquery入门
jquery: 1.jQuery 对象就是通过jQuery包装DOM对象后产生的对象. jQuery对象是jQuery独有的.假设一个对象是jQuery对象,那么它就能够使用jQuery里的方法:$( ...
- jQuery EasyUI 数据网格 - 条件设置行背景颜色
$('#tt').datagrid({ rowStyler:function(index,row){ if (row.listprice>50){ return 'color:blue;font ...
- Win7+Qt5.6.0(64位)+msvc2015编译器 环境配置
根据“Qt简介,Qt 5.6.0-VS2015 版本安装配置图文教程”安装第二套IDE,使用Qt官方的集成开发环境 QtCreator + 微软的WinDbg调试器(内含命令行调试器为CDB)的组合. ...
- go语言基础之 if else的使用
一.if_else 示例1: package main //必须有一个main包 import "fmt" func main() { a := 11 if a == 10 { f ...