• ASP.NET中httpmodules与httphandlers全解析


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

    https://www.cnblogs.com/PiaoMiaoGongZi/p/5216089.html

    https://www.cnblogs.com/xcsn/p/6939628.html

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

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

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

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

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

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

      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代码。

      2、身份检查

      大家在作登录时,登录成功后,一般要把用户名放在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>

      3、多模块的操作

      如果定义了多个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。

  • 相关阅读:
    rabbitmq-高级(死信队列)
    rabbitmq-高级(TTL过期时间)
    springboot整合rabbitmq(topic主题模式)
    springboot整合rabbitmq(direct路由模式)
    glide图片加载库
    自己封装的OKhttp请求
    手机上搭建微型服务器
    listview实现点击条目上的箭头展开隐藏菜单。
    recycleview + checkbox 实现单选
    recycleview中使用checkbox导致的重复选中问题
  • 原文地址:https://www.cnblogs.com/liuqiyun/p/11732057.html
Copyright © 2020-2023  润新知