ASP.NET中httpmodules与httphandlers全解析

https://www.cnblogs.com/zpc870921/archive/2012/03/12/2391424.htmlhtml

http://www.javashuo.com/article/p-zhkriyjs-hh.htmlweb

http://www.javashuo.com/article/p-dhxrsxbr-hn.html服务器

一、向每一个页面动态添加一些备注或说明性的文字:函数

  有的网站每个页面都会弹出一个广告或在每一个页面都以注释形式(<!-- -->)加入网站的版权信息。若是在每一个页面教编写这样的JS代码的话,对于大一点的网站,这种JS代码的编写与维护但是一个很繁琐枯燥的工做。网站

  有了HttpModule咱们就能够很简单地解决这个问题了。HttpModule是客户端发出请求到客户端接收到服务器响应之间的一段必经之 路。咱们彻底能够在服务器处理完请求以后,并在向客户端发送响应文本以前这段时机,把这段注释文字添加到页面文本以后。这样,每个页面请求都会被附加上 这段注释文字。ui

  这段代码究竟该在哪一个事件里实现呢? PostRequestHandlerExecute和PreSendRequestContent之间的任何一个事件均可以,但我比较喜欢在EndRequest事件里编写代码。orm

  第一步:建立一个类库ClassLibrary831。htm

  第二步:编写一个类实现IHttpModule接口blog

  class TestModule:IHttpModule接口

  {

  public void Dispose()

  {

  }

  public void Init(HttpApplication context)

  {

  }

  }

  第三步:在Init事件中注册EndRequest事件,并实现事件处理方法

  class TestModule:IHttpModule

  {

  public void Dispose(){}

  public void Init(HttpApplication context)

  {

  context.EndRequest += new EventHandler(context_EndRequest);

  }

  void context_EndRequest(object sender, EventArgs e)

  {

  HttpApplication ha = (HttpApplication)sender;

  ha.Response.Write("<!--这是每一个页面都会动态生成的文字。--grayworm-->");

  }

  }

  第四步:在Web.Conofig中注册一下这个HttpModule模块

  <httpModules>

  <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>

  </httpModules>

  name:模块名称,通常是类名

  type:有两部分组成,前半部分是命名空间和类名组成的全名,后半部分是程序集名称,若是类是直接放在App_Code文件夹中,那程序名称是App_Code。

  这样在Web站点是添加该类库的引用后,运行每一个页面,会发现其源文件中都会加入“<!--这是每一个页面都会动态生成的文字。--grayworm-->”这句话。一样的方法你也能够在其中加入JS代码。

  二、身份检查

  你们在做登陆时,登陆成功后,通常要把用户名放在Session中保存,在其它每个页面的Page_Load事件中都检查Session中是否存在用户名,若是不存在就说明用户未登陆,就不让其访问其中的内容。

  在比较大的程序中,这种作法实在是太笨拙,由于你几乎要在每个页面中都加入检测Session的代码,致使难以开发和维护。下面咱们看看如何使用HttpModule来减小咱们的工做量

  因为在这里咱们要用到Session中的内容,咱们只能在AcquireRequestState和 PreRequestHandlerExecute事件中编写代码,由于在HttpModule中只有这两事件中能够访问Session。这里咱们选择 PreRequestHandlerExecute事件编写代码。

  第一步:建立一个类库ClassLibrary831。

  第二步:编写一个类实现IHttpModule接口

  class TestModule:IHttpModule

  {

  public void Dispose()

  {

  }

  public void Init(HttpApplication context)

  {

  }

  }

  第三步:在Init事件中注册PreRequestHandlerExecute事件,并实现事件处理方法

  class AuthenticModule:IHttpModule

  {

  public void Dispose(){}

  public void Init(HttpApplication context)

  {

  context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);

  }

  void context_PreRequestHandlerExecute(object sender, EventArgs e)

  {

  HttpApplication ha = (HttpApplication)sender;

  string path = ha.Context.Request.Url.ToString();

  int n = path.ToLower().IndexOf("Login.aspx");

  if (n == -1) //是不是登陆页面,不是登陆页面的话则进入{}

  {

  if (ha.Context.Session["user"] == null) //是否Session中有用户名,如果空的话,转向登陆页。

  {

  ha.Context.Response.Redirect("Login.aspx?source=" + path);

  }

  }

  }

  }

 

 

第四步:在Login.aspx页面的“登陆”按钮中加入下面代码

  protected void Button1_Click(object sender, EventArgs e)

  {

  if(true)    //判断用户名密码是否正确

  {

  if (Request.QueryString["source"] != null)

  {

  string s = Request.QueryString["source"].ToLower().ToString();   //取出从哪一个页面转来的

  Session["user"] = txtUID.Text;

  Response.Redirect(s); //转到用户想去的页面

  }

  else

  {

  Response.Redirect("main.aspx");    //默认转向main.aspx

  }

  }

  }

  第五步:在Web.Conofig中注册一下这个HttpModule模块

  <httpModules>

  <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>

  </httpModules>

  三、多模块的操做

  若是定义了多个HttpModule,在web.config文件中引入自定义HttpModule的顺序就决定了多个自定义HttpModule在处理一个HTTP请求的接管顺序。

  HttpHandler

  HttpHandler是HTTP请求的处理中心,真正地对客户端请求的服务器页面作出编译和执行,并将处理事后的信息附加在HTTP请求信息流中再次返回到HttpModule中。

  HttpHandler与HttpModule不一样,一旦定义了本身的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。

  IHttpHandler接口声明

  public interface IHttpHandler

  {

  bool IsReusable { get; }

  public void ProcessRequest(HttpContext context); //请求处理函数

  }

  示例:把硬盘上的图片以流的方式写在页面上

  class TestHandler : IHttpHandler

  {

  public void ProcessRequest(HttpContext context)

  {

  FileStream fs = new FileStream(context.Server.MapPath("worm.jpg"), FileMode.Open);

  byte[] b = new byte[fs.Length];

  fs.Read(b, 0, (int)fs.Length);

  fs.Close();

  context.Response.OutputStream.Write(b, 0, b.Length);

  }

  public bool IsReusable

  {

  get

  {

  return true;

  }

  }

  }

  Web.Config配置文件

  <httpHandlers>

  <add verb="*" path="*" type="ClassLibrary831.TestHandler,ClassLibrary831"></add>

  </httpHandlers>

  Verb属性:指定了处理程序支持的HTTP动做。*-支持全部的HTTP动做;“GET”-支持Get操做;“POST”-支持Post操做;“GET, POST”-支持两种操做。

  Path属性:指定了须要调用处理程序的路径和文件名(能够包含通配符)。“*”、“*.aspx”、“showImage.aspx”、“test1.aspx,test2.aspx”

  Type属性:用名字空间、类名称和程序集名称的组合形式指定处理程序或处理程序工厂的实际类型。ASP.NET运行时首先搜索bin目录中的DLL,接着在GAC中搜索。

  这样程序运行的效果是该网站的任何一个页面都会显示worm.jpg图片。如何只让一个页面(default21.aspx)执行 HttpHandler中的ProcessRequest方法呢?最简单的办法是在Web.Config文件中把path配置信息设为 default21.aspx。

相关文章
相关标签/搜索