熟悉 ASP.NET 架构的开发者一定对于 HTTP Modules 与 HTTP Handlers 不陌生. 两者的作用主要是对网络请求执行特定的处理工作. 而在. NET Core 中, 它们都被 Middleware(中件间)取代了.
之前的 Http Modules 和 HTTP Handlers 是如下图般处理请求的:
现在变成了这样:
一言概括之, Middleware 完成了 HTTP Modules 与 HTTP Handlers 的原有工作, 但又不是简单的化二为一的减法作用.
Middleware 减去的其实是与原来 ASP.NET 中重要的基础 -- 应用程序生命周期事件 (application life cycle event https://msdn.microsoft.com/en-us/library/ms178473(v=vs.85).aspx ) 的绑定.
HTTP Modules 在初始化时就需要针对 HttpApplication 的事件作绑定处理, 这样当 HttpApplication 的各项事件被触发时, 已绑定的相应处理程序才会按照预期的那样被执行.
- public class HelloWorldModule : IHttpModule
- {
- public HelloWorldModule()
- {
- }
- public String ModuleName
- {
- get { return "HelloWorldModule"; }
- }
- // In the Init function, register for HttpApplication
- // events by adding your handlers.
- public void Init(HttpApplication application)
- {
- application.BeginRequest +=
- (new EventHandler(this.Application_BeginRequest));
- application.EndRequest +=
- (new EventHandler(this.Application_EndRequest));
- }
- private void Application_BeginRequest(Object source,
- EventArgs e)
- {
- // Create HttpApplication and HttpContext objects to access
- // request and response properties.
- HttpApplication application = (HttpApplication)source;
- HttpContext context = application.Context;
- context.Response.Write("<h1><font color=red>
- HelloWorldModule: Beginning of Request
- </font></h1><hr>");
- }
- private void Application_EndRequest(Object source, EventArgs e)
- {
- HttpApplication application = (HttpApplication)source;
- HttpContext context = application.Context;
- context.Response.Write("<hr><h1><font color=red>
- HelloWorldModule: End of Request</font></h1>");
- }
- public void Dispose()
- {
- }
- }
然后你还需要在 web.config 配置文件注册这个 HTTP Module.
- <configuration>
- <system.web>
- <httpModules>
- <add name="HelloWorldModule" type="HelloWorldModule"/>
- </httpModules>
- </system.web>
- </configuration>
如果是用 Middleware 的话, 事情就变得很简单了. 抛弃 IHttpModule 接口及 HttpModule 实现类, 不用再关心 HttpApplication 的任何事件, 还有烦人的 web.config 配置. 直接在代码中以最简洁的方式完成工作.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- app.Use(async(context, next) =>{
- await context.Response.WriteAsync("Beginning of Request\n");
- await next.Invoke();
- await context.Response.WriteAsync("End of Request\n");
- });
- app.Run(async (context) =>
- {
- await context.Response.WriteAsync("Hello World!\n");
- });
- }
相似的, 对于 HTTP Handlers, 虽然不用取消对 HttpApplication 事件的依赖, 但以两者的代码实现方式作比较, Middleware 亳无疑问胜出一筹.
- public class HelloWorldHandler : IHttpHandler
- {
- public HelloWorldHandler()
- {
- }
- public void ProcessRequest(HttpContext context)
- {
- HttpRequest Request = context.Request;
- HttpResponse Response = context.Response;
- // This handler is called whenever a file ending
- // in .sample is requested. A file with that extension
- // does not need to exist.
- Response.Write("<html>");
- Response.Write("<body>");
- Response.Write("<h1>Hello from a synchronous custom HTTP handler.</h1>");
- Response.Write("</body>");
- Response.Write("</html>");
- }
- public bool IsReusable
- {
- // To enable pooling, return true here.
- // This keeps the handler in memory.
- get { return false; }
- }
- }
仍需要在 web.config 文件中注册 HTTP handler.
- <configuration>
- <system.web>
- <httpHandlers>
- <add verb="*" path="*.sample"
- type="HelloWorldHandler"/>
- </httpHandlers>
- </system.web>
- </configuration>
换作 Middleware 的写法:
- private static void HandleSample(IApplicationBuilder app)
- {
- app.Run(async context =>
- {
- await context.Response.WriteAsync("Hello Sample");
- });
- }
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- app.MapWhen(context => context.Request.Path.Value.EndsWith("sample"), HandleSample);
- }
总结下使用 Middleware 的优点:
没有对 HttpApplication 的依赖
没有对 IHttpModule 与 IHttpHandler 接口的依赖
无需在 web.config 文件中添加各种配置
代码简洁
最后需要补充 Middleware 与 HTTP Modules 的一点差异. 各 Middleware 中处理请求与响应的顺序是刚好相反的, 越早处理请求的 Middleware 越晚处理响应. 而 HTTP Modules 中处理请求与响应的顺序则保持一致, 因为每个 HTTP Module 请求与响应事件的绑定都是在同一阶段完成的.
来源: https://www.cnblogs.com/kenwoo/p/9275922.html