• HttpHandle


    很多时候,我们新建一个xxx.aspx页和xxx.aspx.cs文件,不过是为了实现一个很简单的功能,如:输出xmlDom,注销并跳转,并没有什么html的输出,很是麻烦,需要新建一个页,删除多余的html,并在 page_load里面写处理代码。而使用HttpHandler就不需要这么麻烦了。

    可以用任何符合公共语言规范 (CLS) 的语言编写自定义 HTTP 处理程序来处理特定的、预定义类型的 HTTP 请求。响应这些特定请求的是在 HttpHandler 类中定义的可执行代码,而不是常规的 ASP 或 ASP.NET Web 页。HTTP 处理程序向您提供一种方法,使您可以与 IIS Web 服务器的低级别的请求和响应服务交互,同时提供极其类似于 ISAPI 扩展但编程模型较为简单的功能。

    例如我现在需要实现一个注销并跳转的Logout.aspx页面,下面的示例主要实现了响应客户端对名为 logout.aspx 的页的请求,实现注销并跳转。对 logout.aspx 的所有请求均由包含在程序集 WebUC.dll 中的命名空间 WebUC.HttpHandler 中的 LogoutHttpHandler 提供服务。

    修改web.config,在<system.web></system.web>中增加如下脚本:
    <httpHandlers>
     <add verb="GET" path="Logout.aspx" type="WebUC.HttpHandler.LogoutHttpHandler, WebUC" />
    </httpHandlers>
    其中WebUC.HttpHandler.LogoutHttpHandler是我要实现Logout.aspx功能的类,WebUC是我web项目的dll。(具体介绍可以参阅msdn)

    下面是LogoutHttpHandler的代码,继承借口,重写方法和属性。

    using System;
    using System.Web;
    using System.Web.Caching;
    using System.Web.Security;

    namespace WebUC.HttpHandler 
    {

     public class LogoutHttpHandler : IHttpHandler 
     {
      /// <summary>
      /// 通过实现 IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
      /// </summary>
      /// <param name="context">HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。 </param>
      public void ProcessRequest (HttpContext context) 
      {
       FormsAuthentication.SignOut();
       context.Response.Redirect("Login.aspx",true);
      }

      /// <summary>
      /// 获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。
      /// </summary>

      public bool IsReusable 
      {
       get 
       {
        return false;
       }
      }
     }

     }
    }

    编译后,我就可以直接使用http://%2a%2a%2a/logout.aspx 来实现注销了,而实际上,我的web目录下并没有logout.aspx这个文件,同样,这个技巧可以用在很多方面,例如防止盗链,下载统计等。 

    ASP.NET中的Http Handles    

    一、关于http handles
        ASP.NET的请求过程是基于一个管道(pipeline)模型的,ASP.NET会把所有的http请求(Requests)都发送给这个管道里的 http组件(modules)。每个组件在接收到http请求后进行一些相应的动作。当http请求通过了所有的http modules程序后,将会被交由一个http handle程序来处理,处理后的结果又将通过管道里http modules返回。这整个过程中,被调用的http module可以有多个,然而调用的http handle只能是一个。其过程如图:

        可以看出每个输入的http请求都会最终被一个http handle程序处理。http handle是一个实现了System.Web.IHttpHandler接口的类的实例,有些类似ISAPI扩展。在http handles中实现的有:
    ProcessRequest:该方法用来处理http请求,是http handles最核心的方法
    IsReusable:一个属性,返回一个bool值,来表示这http handle的实例是否能被重用来处理多个同类型的http请求。

    二、在配置文件中注册http handles
        http handles的类可以在web.config或machine.config文件里注册。这样,一旦有相应的http请求输入,这个http handle类就会被实例化。在web.config或machine.config文件里我们用<httpHandlers> 和<add>节点来为我们的应用程序添加http handle类:
    <httpHandlers>
     <add verb="supported http verbs" path="path" type="namespace.classname, assemblyname" />
    <httpHandlers>

    在<add>里
    1、verb属性说明了该handle所支持的http请求方式,例如支持post和get方式,verb属性则为"POST,GET";如果支持所有的请求方式,verb属性则用"*"。
    2、path属性说明了对哪些文件的请求才调用该handle来处理,例如你只想在请求my.possible文件时才调用该handle,则path属性为"my.possible",如果你想所有后缀名为possible的文件(*.possible)都由该handle来处理,则path属性为"*.possible"。
    3、type属性中指定了handle类的命名空间、类名和配件名(工程名)。ASP.NET runtime会首先到应用程序的bin目录下查找该配件的dll,如果没有找到再到GAC里查找。

    其实ASP.NET自身里的许多功能也是使用HTTP handlers来实现,ASP.NET使用了许多的handle类来处理.aspx, .asmx, .soap 和一些其它的ASP.NET文件。你可以在machine.config文件里找到如下代码:
    <httpHandlers>
    <add verb="*" path="trace.axd" type="System.Web.Handlers.TraceHandler"/>
     
     <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
     
     <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory"/>

     <add verb="*" path="*.config" type="System.Web.HttpForbiddenHandler"/>
     
     <add verb="GET,HEAD" path="*" type="System.Web.StaticFileHandler"/>
     
     . . . . . . 
     . . . . . .
    </httpHandlers>
    从上面的配置可以看出来对.aspx文件的请求是交由System.Web.UI.PageHandlerFactory类来处理的,而象.config文件是被System.Web.HttpForbiddenHandler类来处理,可以猜想这个类将会返回一个该类文件不能被请求的错误。

    三、http handles类的实现
        在这里我们用C#来创建一个新的handle类来处理新的文件类型,比如以.possible为后缀名的文件。
    1、我们先在vs.net里创建web应用程序的工程,名为MyHandler,然后添加一个类文件NewHandler.cs来建立实现了IHttpHandler接口的类:

    using System;
    using System.Web;

    namespace MyHandler
    {
     /// <summary>
     /// Summary description for NewHandler.
     /// </summary>
     public class NewHandler : IHttpHandler
     {
      public NewHandler()
      {
       //
       // TODO: Add constructor logic here
       //
      }

      #region Implementation of IHttpHandler
      public void ProcessRequest(System.Web.HttpContext context)
      {
       HttpResponse objResponse = context.Response ;
       objResponse.Write("<html><body><br><br><center>Hi,This is a test! ") ;
       objResponse.Write("</center></body></html>") ;
      }

      public bool IsReusable
      {
       get
       {
        return true;
       }
      }
      #endregion
     }
    }
    在ProcessRequest方法的实现里,我们只是简单的获取了HttpContext的HttpResponse对象,并象客户端发送了一些html。在IsReusable的实现里返回true,表示该handle类的实例可以处理多个对.possible文件的请求。

    注意:如果想在HTTP handlers里使用session,那么还需要实现IRequiresSessionState接口,而IRequiresSessionState接口只是一个标志,不需要实现任何的具体方法,所以只需要把类申明改为:public class NewHandler : IHttpHandler,IRequiresSessionState即可。

    2、打开web.config文件,注册上面新创建的handle类:
    <httpHandlers>
      <add verb="*" path="*.possible" type="MyHandler.NewHandler,MyHandler"/>
    </httpHandlers>

    3、在IIS中添加ISAPI扩展,将我们的新后缀名.possible添加进去,具体过程为:
    IIS--》选中“默认网站”点右键--》选“属性”--》“主目录”--》“配置”--》点“映射”里的“添加”按钮--》在弹出对话框里点击“浏览”按钮,选择aspnet_isapi.dll文件,并在扩展名里填possible,如下图所示:

    最后点击确定按钮。

    这样我们就可以在浏览器里输入http://localhost/MyHandler/xxx.possible,来调用该handle了。当然我们这里只是举了个简单例子,所以输入任何*.possible都是一样的效果。我们可以在NewHandler的 ProcessRequest方法里先分析请求的url,然后根据不同url作出不同的相应,比如跳转到不同的真实存在的aspx页面,这也正是web设计模式中MVC模式在asp.net中通过Front Controller实现的核心部分之一,具体请见:http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en-us/dnpatterns/html/DesFrontController.asp

  • 相关阅读:
    Day 9 作业题(完成)
    Day 9 函数的初识1
    Day 8 集合与文件的操作
    Day 7 深copy和浅Copy
    Day6 ,周期末考试试题
    Day 6 编码的进阶
    Day5 作业(完成)
    Day 5 字典的操作
    Day4 作业
    Day 4 list 列表的使用方法
  • 原文地址:https://www.cnblogs.com/goody9807/p/1513649.html
Copyright © 2020-2023  润新知