IHttpHandler 与 IHttpModule

Posted

技术标签:

【中文标题】IHttpHandler 与 IHttpModule【英文标题】:IHttpHandler vs IHttpModule 【发布时间】:2010-10-20 15:28:31 【问题描述】:

我的问题很简单(尽管答案很可能不是):我正在尝试决定如何在 C#/ASP.NET 中实现服务器端上传处理程序。

我已经使用了 HttpModules(IHttpModule 接口)和 HttpHandlers(IHttpHandler 接口),我突然想到我可以使用任何一种机制来实现它。我也突然想到,我不明白两者之间的区别。

所以我的问题是:在什么情况下我会选择使用 IHttpHandler 而不是 IHttpModule(反之亦然)?

在管道中执行得更高吗?在某些情况下更容易配置吗?在中等安全性下不能很好地工作吗?

【问题讨论】:

在“我也意识到我不理解两者之间的区别”时,我很认真地笑了。好问题,但它应该只为此 +1 :) :-) 谢谢。我觉得对我不知道的事情诚实是件好事。 没有问题,就没有答案.. :) 【参考方案1】:

ASP.NET HTTP 处理程序 是响应对 ASP.NET Web 应用程序发出的请求而运行的进程(通常称为“端点”)。最常见的处理程序是处理 .aspx 文件的 ASP.NET 页面处理程序。当用户请求 .aspx 文件时,该请求由页面通过页面处理程序进行处理。您可以创建自己的 HTTP 处理程序,将自定义输出呈现给浏览器。

自定义 HTTP 处理程序的典型用途包括:

RSS 提要 要为网站创建 RSS 提要,您可以创建一个发出 RSS 格式的 XML 的处理程序。然后,您可以将文件扩展名(例如 .rss)绑定到自定义处理程序。当用户向您的网站发送以 .rss 结尾的请求时,ASP.NET 会调用您的处理程序来处理该请求。 图像服务器 如果您希望 Web 应用程序提供各种尺寸的图像,您可以编写一个自定义处理程序来调整图像大小,然后将它们作为处理程序的响应发送给用户。

HTTP 模块 是在对您的应用程序发出的每个请求时调用的程序集。 HTTP 模块作为 ASP.NET 请求管道的一部分被调用,并且可以访问整个请求的生命周期事件。 HTTP 模块可让您检查传入和传出请求并根据请求采取行动。

HTTP 模块的典型用途包括:

安全性 因为您可以检查传入的请求,所以 HTTP 模块可以在调用请求的页面、XML Web 服务或处理程序之前执行自定义身份验证或其他安全检查。在以集成模式运行的 Internet Information Services (IIS) 7.0 中,您可以将表单身份验证扩展到应用程序中的所有内容类型。 统计信息和日志记录 因为每个请求都会调用 HTTP 模块,所以您可以在一个集中的模块中而不是在单个页面中收集请求统计信息和日志信息。 自定义页眉或页脚 因为您可以修改传出响应,所以可以将自定义页眉信息等内容插入到每个页面或 XML Web 服务响应中。

发件人:http://msdn.microsoft.com/en-us/library/bb398986.aspx

【讨论】:

【参考方案2】:

如here 所述,HttpModules 是简单的类,可以将自己插入请求处理管道,而 HttpHandler 与 HttpModules 的不同之处不仅在于它们在请求处理管道中的位置,还因为它们必须映射到特定的文件扩展名。

【讨论】:

如果在 HttpModule 中显式解析为实现 iHttpHandler 的类,则无需将处理程序映射到扩展 @rizzle:“显式解析为实现 IHttpHandler 的类”是什么意思?你的意思是 IHttpModule 也是一个 IHttpHandler 吗? @Ryan:在模块中,您可以将方法附加到 HttpApplication.BeginRequest 事件并为其提供您选择的处理程序,而不管文件扩展名如何【参考方案3】:

IHttpModule 为您提供更多控制权,您基本上可以控制所有指向您的 Web 应用程序的流量。 IHttpHandler 为您提供较少的控制(流量在到达您的处理程序之前被过滤),但如果这足以满足您的需求,那么我认为没有理由使用 IHttpModule

无论如何,最好将您的自定义逻辑放在一个单独的类中,然后只使用来自IHttpModuleIHttpHandler 的这个类。这样您就不必担心选择其中一个。事实上,您可以创建一个额外的类来实现 both IHttpHandlerIHttpModule,然后通过在 Web.config 中设置它来决定使用什么。

【讨论】:

谢谢你能解释一下,说我们正在向 Web 服务器添加自定义身份验证以用于远程请求,但不用于本地请求吗?【参考方案4】:

模块旨在处理应用程序在处理程序实际处理请求之前和之后引发的事件。另一方面,处理程序没有机会订阅任何应用程序事件,而是简单地调用其 ProcessRequest 方法,以便处理特定请求的“主要”工作。

查看 Microsoft 的此文档(大约在“请求由 HttpApplication 管道处理”部分的页面下方):

http://msdn.microsoft.com/en-us/library/bb470252.aspx

您可以在第 15 步中看到处理程序有机会执行。该步骤之前和之后的所有事件都可以被模块拦截,但不能被处理程序拦截。

根据您要实现的特定功能,您可以使用处理程序或模块来实现上传处理程序。您甚至可能最终同时使用两者。

需要考虑的可能是使用已经编写好的上传处理程序。

这是一个免费和开源的:

http://www.brettle.com/neatupload

这是一个商业广告:

http://krystalware.com/Products/SlickUpload/

如果您查看 NeatUpload 的文档,您会发现它需要您配置一个模块。

【讨论】:

【参考方案5】:

15秒有个不错的小tutorial举个实际例子

【讨论】:

这篇文章现在可以在codeguru上找到:codeguru.com/csharp/.net/net_asp/article.php/c19389/…

以上是关于IHttpHandler 与 IHttpModule的主要内容,如果未能解决你的问题,请参考以下文章

IHttpHandler

System.Web.Routing.UrlRoutingModule 未实现 IHttpHandlerFactory 或 IHttpHandler

使用一般处理程序(IHttpHandler)制作图片水印

ASP.NET MVC5请求管道和生命周期

ASP.NET MVC5请求管道和生命周期

HttpModule 介绍