.NET Core开发日志——Middleware
熟悉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)的绑定。
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请求与响应事件的绑定都是在同一阶段完成的。
.NET Core开发日志——Middleware的更多相关文章
- .NET Core开发日志——RequestDelegate
本文主要是对.NET Core开发日志--Middleware的补遗,但是会从看起来平平无奇的RequestDelegate开始叙述,所以以其作为标题,也是合情合理. RequestDelegate是 ...
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...
- .NET Core开发日志——Entity Framework与PostgreSQL
Entity Framework在.NET Core中被命名为Entity Framework Core.虽然一般会用于对SQL Server数据库进行数据操作,但其实它还支持其它数据库,这里就以Po ...
- ASP.NET Core 开发-中间件(Middleware)
ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...
- .NET Core开发日志——从搭建开发环境开始
.NET Core自2016年推出1.0版本开始,到目前已是2.1版本,在其roadmap计划里明年更会推出3.0版本,发展不可不谓之迅捷.不少公司在经过一个谨慎的观望期后,也逐步开始将系统升级至最新 ...
- .NET Core开发日志——简述路由
有过ASP.NET或其它现代Web框架开发经历的开发者对路由这一名字应该不陌生.如果要用一句话解释什么是路由,可以这样形容:通过对URL的解析,指定相应的处理程序. 回忆下在Web Forms应用程序 ...
- .NET Core开发日志——GraphQL
GraphQL是什么 GraphQL既是一种用于API的查询语言也是一种通过使用对应数据的类型系统,执行数据查询的服务端运行时.GraphQL没有局限于任何数据库或存储引擎,而是通过既有代码及数据获得 ...
- .NET Core开发日志——结构化日志
在.NET生态圈中,最早被广泛使用的日志库可能是派生自Java世界里的Apache log4net.而其后来者,莫过于NLog.Nlog与log4net相比,有一项较显著的优势,它支持结构化日志. 结 ...
- .NET Core开发日志——Edge.js
最近在项目中遇到这样的需求:要将旧有系统的一部分业务逻辑集成到新的自动化流程工具中.这套正在开发的自动化工具使用的是C#语言,而旧有系统的业务逻辑则是使用AngularJS在前端构建而成.所以最初的考 ...
随机推荐
- VTK拾取网格模型上的可见点
消隐与Z-Buffer 使用缓冲器记录物体表面在屏幕上投影所覆盖范围内的全部像素的深度值,依次访问屏幕范围内物体表面所覆盖的每一像素,用深度小(深度用z值表示,z值小表示离视点近)的像素点颜色替代深度 ...
- 内核编译之vmlinuz vmlinux system.map initrd
一.vmlinuz vmlinuz是可引导的.压缩的内核.“vm”代表“Virtual Memory”.Linux 支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制.Linux能够使用 ...
- iOS关于沙盒文件拷贝manager.copyItem的一个坑
记录一下: 沙盒文件操作,当需要拷贝文件时,我们可以使用如下类似方式: // 文件拷贝 func copyFile(from:String,to:String)->Bool{ if !manag ...
- ubuntu下解压文件命令大全(转)
ubuntu 下rar解压工具安装方法: 压缩功能 安装 sudo apt-get install rar卸载 sudo apt-get remove rar 解压功能 安装 sudo apt-get ...
- Benchmark Web App 性能瓶颈分析与性能测试工具的使用方法总结
主要分为以下几个要素的指标: Disk IO . CPU . mem . Net . MySQL Web性能测试工具: 客户端 服务器端: 服务器性能测试工具: 服务器性能瓶颈分析工具: ab, si ...
- 本地搭建Wooyun漏洞库环境
众所周知,wooyun上有太多含金量的漏洞了,虽然互联网上也有相关的漏洞资源分享,但是万一有朝一日也被和谐了就又麻烦了,最放心的方式就是漏洞库放在本地,在本地搭建一套环境最好不过了,以下操作演示了如何 ...
- ImageView setImageURI图片不改变\NetWorkImageView 不显示的问题
ImageView 问题描述:图片文件已改变,第二次调用ImageView.setImageURI时无法更新图片 分析:setImageURI方法中对uri进行了缓存,由于第一次加载过了该uri的资源 ...
- GPT(保护分区)解决办法
教你在硬盘被GPT保护分区后怎么格式化 GUID 分区表 (GPT) 作为可扩展固件接口 (EFI) 计划的一部分而引入.与 PC 以前通用的旧的主引导记录 (MBR) 分区方案相比,GPT 为磁盘 ...
- Zookeeper系列四:Zookeeper实现分布式锁、Zookeeper实现配置中心
一.Zookeeper实现分布式锁 分布式锁主要用于在分布式环境中保证数据的一致性. 包括跨进程.跨机器.跨网络导致共享资源不一致的问题. 1. 分布式锁的实现思路 说明: 这种实现会有一个缺点,即当 ...
- Ubuntu系统搭建SVN服务器
Ubuntu系统搭建SVN服务器 参考地址:http://git.devzeng.com/blog/aliyun-ubuntu-svn-server.html 安装软件 依次在终端中执行下面的命令安装 ...