• 关于HttpHandler和HttpModule的使用选择问题
  • Tmac 发表于 2015/12/29 13:49:00 | 分类标签: HttpHandler 处理对象
  •  HttpHandler是每个请求的主要处理对象,而HttpModule可以选择请求交给哪个HttpHandler来处理, 甚至,它还可以选择它自己来处理请求。

    下面我给个示例代码来说明HttpModule也能直接请求:

    /// <summary>
    /// 此Module示范了直接使用Module也能处理客户端的请求。
    /// 建议:除非要很好的理由,否则不建议使用这种方法。
    /// </summary>
    internal class DirectProcessRequestMoudle : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            app.PostAuthorizeRequest += new EventHandler(app_PostAuthorizeRequest);
        }
    
        void app_PostAuthorizeRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
    
            ServiceInfo info = GetServiceInfo(app.Context);
            if( info == null )
                return;
    
            ServiceExecutor.ProcessRequest(app.Context, info);
            app.Response.End();
        }
    

    为了更好的回答本节的这个问题,我再给段等效的代码,不过,请求是经过HttpHandler来处理

    internal class MyServiceHandler : IHttpHandler
    {
        internal ServiceInfo ServiceInfo { get; set; }
    
        public void ProcessRequest(HttpContext context)
        {
            ServiceInfo info = this.ServiceInfo ?? GetServiceInfo(context);
    
            ServiceExecutor.ProcessRequest(context, info);
        }
    

    HttpHandler和HttpModule都能处理请求,我该选哪个??

    对于此类情况,我的答案是:视情况而定,正如我在注释中描述的那样,除非要很好的理由,否则不建议使用HttpModule处理请求。 用HttpModule在某些时候可能会快点,关键点在于处理完成时要调用Response.End();这会让后面的事件全都短路, 其它的HttpModule就没有机会执行。如果您的框架或者项目设计很依赖于管线中的事件处理,那么调用Response.End();无疑会破坏这个规则, 也将会导致不能得到正确的结果。选择HttpHandler就不会有这种事情发生。

    不过,也没有绝对的事情:在请求处理期间,您可以在任何地方调用Response.End(); 结果也是一样的。

    幸好,短路的情况并不经常发生,因此选择HttpHandler会让整个Asp.net的管线都能发挥作用,因此,我建议优先选择HttpHandler。
    尤其是在HttpHandler能很好的完成工作的前提下,就应该选HttpHandler,因为选HttpModule会给其它请求带来不必要的性能损失, 具体细节请继续阅读。

    其实,我们还可以从另一个角度来看这个问题。
    首先,请仔细地阅读前面的示例代码,您是否发现它们在实现方式上非常类似?
    现在应该找到答案了吧:把具体的处理操作分离到HttpHandler,HttpModule之外的地方。 那么,此时这个问题也就不是问题了,您也可以提供多种方案供使用者选择。 比如:我就为【我的服务框架】提供了5种方式让使用者可以轻松地将一个C#方法公开为一个服务方法, 该如何选择这个问题,由使用者来决定,这个问题不会让我为难。

    我的观点:在没有太多技术难度的前提下,提供多种解决办法应该是对的,您将会避开很多麻烦事情。

  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:Tmac
  • 加入时间:2013/6/13 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮