ASP.Net MVC 中的 HTTP 模块和 HTTP 处理程序?

HTTP modules and HTTP handlers in ASP.Net MVC?

我在采访中被问到如何在 ASP.Net MVC 中实现 HTTP moduleHTTP handler 的问题。我知道它们在ASP.Net中被用来编写aspx页面调用前的预处理逻辑。但是在 ASP.Net MVC 中我们有过滤器,所以我告诉他们我们为此使用过滤器。我给出了正确的答案吗?

Action Filters 允许您仅挂接到 MVC 特定事件,而 HTTP 模块 允许您连接到 ASP.Net 事件。因此,即使在 MVC 中,要实现 HTTP 模块和 HTTP 处理程序,您也需要实现相应的接口。

  • 如果您希望每个 Http 请求只执行一次您的功能,您应该使用 HttpModule。
  • ActionFilters 可能会在一次访问服务器的过程中执行多次。

为了解释 HTTP 模块和 HTTP 处理程序,MVC 使用 HTTP 模块和 HTTP 处理程序在请求链中注入 pre-processing 逻辑。

  • HTTP 处理程序是基于扩展的 pre-processor 而 HTTP 模块是基于事件的预处理器。
    • 例如: 如果你想改变 jpg 文件的处理方式,你将实现自定义 HTTP 处理程序,如果你想在处理过程中执行额外的逻辑请求,您将实现自定义 HTTP 模块。对于特定请求始终只有一个 HTTP 处理程序,但可以有多个 HTTP 模块。

要实现 HTTP 处理程序:

您实施 IHttpHandler class 并实施 ProcessRequest 方法和 IsResuable 属性。 IsResuable 属性 判断handler是否可以重用

public class MyJpgHandler: IHttpHandler 
{

    public bool IsReusable => false;

    public void ProcessRequest(HttpContext context) 
    {
       // Do something
    }
}

接下来我们需要在 web.config 文件中指定我们的自定义处理程序将处理哪种请求:

<httpHandlers>
    <add verb="*" path="*.jpg" type="MyJpgHandler"/>
</httpHandlers>

实现HTTP模块:

我们需要实现 IHttpModule 并在 Init 方法中注册所需的事件。举个简单的例子,如果我们想记录所有的请求:

public class MyHttpModule: IHttpModule 
{

    public MyHttpModule() {}

    public void Init(HttpApplication application) 
    {
        application.BeginRequest += new EventHandler(this.context_BeginRequest);
        application.EndRequest += new EventHandler(this.context_EndRequest);
    }

    public void context_BeginRequest(object sender, EventArgs e) 
    {
        StreamWriter sw = new StreamWriter(@ "C:\log.txt", true);
        sw.WriteLine("Request began at " + DateTime.Now.ToString());
        sw.Close();
    }

    public void context_EndRequest(object sender, EventArgs e) 
    {
        StreamWriter sw = new StreamWriter(@ "C:\log.txt", true);
        sw.WriteLine("Request Ended at " + DateTime.Now.ToString());
        sw.Close();
    }

    public void Dispose() {}
}

并在 web.config 文件中注册我们的模块:

<httpModules>
    <add name="MyHttpModule " type="MyHttpModule " />
</httpModules>