[译]Writing Custom Middleware in ASP.NET Core 1.0
2016-07-26 17:29
1031 查看
原文: https://www.exceptionnotfound.net/writing-custom-middleware-in-asp-net-core-1-0/
Middleware是ASP.NET Core 1.0的新特性。Middleware用来检测request和response的输入输出。
Middleware可以用来替代HttpModules和HttpHandlers的工作。
在上面的方法中,那些app.UserX(),就意味着使用了ASP.NET默认的Middleware组件。
Middleware可以做许多事。例如:
你想检查每一次request,如果request请求的是一个图片,将请求redirect的一个图片handler。
你想有一个组件用来记录每一次http请求
..........
这个Middleware可以做两件事情:
如果HTTP请求头包含"X-Cancel-Request"那么服务器之间返回500
如果HTTP请求头包含"X-Transfer-By"服务器给响应头加上"X-Transfer-Success"
定义一个ProcessingTimeMiddleware
上面的Middleware用到了Stopwatch,这个组件记录请求响应的时间,并将其作为响应头返回给客户。
另一种是我推荐使用的方法,为每个你想注册的Middleware添加一个扩展方法,然后在
现在可以在Starup中使用这些扩展方法了(仔细读下面的代码,它包含一个Bug)
发现这个Bug了没?
当你注册Middleware时,你添加Middleware的顺序非常重要。上面的代码中,我们首先添加了ProcessingTimeMiddleware, 然后添加RequestHeaderMiddleware,最后添加的是AuthorizationMiddleware。 这个顺序恰好搞反了。 正确的顺序如下:
Middleware能让我们完全控制Http管道
Middleware可以处理验证,重定向,HTTP头,甚至取消HTTP请求
在Startup中注册Middleware的顺序非常重要
本文源码-github
Middleware是ASP.NET Core 1.0的新特性。Middleware用来检测request和response的输入输出。
什么是Middleware?
Middleware是用来检测request和response的组件。Pipeline如下:Middleware可以用来替代HttpModules和HttpHandlers的工作。
默认的Middleware
使用VS创建的ASP.NET Core的应用,默认就使用了Middleware.public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseBrowserLink(); //Middleware app.UseDeveloperExceptionPage(); //Middleware } else { app.UseExceptionHandler("/Home/Error"); //Middleware } app.UseIISPlatformHandler(); //Middleware app.UseStaticFiles(); //Middleware app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); //Middleware }
在上面的方法中,那些app.UserX(),就意味着使用了ASP.NET默认的Middleware组件。
自定义Middleware组件
Middleware组件和其他的class基本一样, 不同的是Middleware有一个类型为RequestDelegate的私有属性,如下:
public class AuthorizationMiddleware { private readonly RequestDelegate _next; public AuthorizationMiddleware(RequestDelegate next) { _next = next; } }
_next属性是一个委托,为Pipeline中下一个组件所用。 每个Middleware都实现一个async任务:
public async Task Invoke(HttpContext context) { await _next.Invoke(context); }
Middleware任务
下面我们新建一个Middleware用于检查HTTP头,如果HTTP头有"X-Not-Authorized",直接返回401。代码如下:public async Task Invoke(HttpContext context) { if (context.Request.Headers.Keys.Contains("X-Not-Authorized")) { context.Response.StatusCode = 401; //Unauthorized return; } await _next.Invoke(context); }
Middleware可以做许多事。例如:
你想检查每一次request,如果request请求的是一个图片,将请求redirect的一个图片handler。
你想有一个组件用来记录每一次http请求
..........
其他Middleware的例子
定义一个RequestHeaderMiddlewarepublic class RequestHeaderMiddleware { private readonly RequestDelegate _next; public RequestHeaderMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { if (context.Request.Headers.Keys.Contains("X-Cancel-Request")) { context.Response.StatusCode = 500; return; } await _next.Invoke(context); if (context.Request.Headers.Keys.Contains("X-Transfer-By")) { context.Response.Headers.Add("X-Transfer-Success", "true"); } } }
这个Middleware可以做两件事情:
如果HTTP请求头包含"X-Cancel-Request"那么服务器之间返回500
如果HTTP请求头包含"X-Transfer-By"服务器给响应头加上"X-Transfer-Success"
定义一个ProcessingTimeMiddleware
public class ProcessingTimeMiddleware { private readonly RequestDelegate _next; public ProcessingTimeMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { var watch = new Stopwatch(); watch.Start(); await _next(context); context.Response.Headers.Add("X-Processing-Time-Milliseconds", new[] { watch.ElapsedMilliseconds.ToString() }); } }
上面的Middleware用到了Stopwatch,这个组件记录请求响应的时间,并将其作为响应头返回给客户。
添加Middeware到HTTP管道中
有两种方法将Middleware注册到pipeline中。 一种是在Startup文件的
Configure方法中调用
IApplicationBuilder的
UseMiddleware方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { ... app.UseMiddleware<AuthorizationMiddleware>(); ... }
另一种是我推荐使用的方法,为每个你想注册的Middleware添加一个扩展方法,然后在
Configure中调用。代码如下:
public static class MiddlewareExtensions { public static IApplicationBuilder UseRequestHeaderMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<RequestHeaderMiddleware>(); } public static IApplicationBuilder UseAuthorizationMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<AuthorizationMiddleware>(); } public static IApplicationBuilder UseProcessingTimeMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<ProcessingTimeMiddleware>(); } }
现在可以在Starup中使用这些扩展方法了(仔细读下面的代码,它包含一个Bug)
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseIISPlatformHandler(); app.UseStaticFiles(); app.UseProcessingTimeMiddleware(); app.UseRequestHeaderMiddleware(); app.UseAuthorizationMiddleware(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
发现这个Bug了没?
当你注册Middleware时,你添加Middleware的顺序非常重要。上面的代码中,我们首先添加了ProcessingTimeMiddleware, 然后添加RequestHeaderMiddleware,最后添加的是AuthorizationMiddleware。 这个顺序恰好搞反了。 正确的顺序如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { ... app.UseAuthorizationMiddleware(); app.UseRequestHeaderMiddleware(); app.UseProcessingTimeMiddleware(); ... }
总结
记住下面3点:Middleware能让我们完全控制Http管道
Middleware可以处理验证,重定向,HTTP头,甚至取消HTTP请求
在Startup中注册Middleware的顺序非常重要
本文源码-github
相关文章推荐
- Entity Framework添加记录时获取自增ID值
- WebService的开发、部署、调用
- 使自己做的asp.net网页适应手机浏览
- ASP.NET Core开发-读取配置文件Configuration
- Raspberry pi2串口通信
- Asp.Net 之 二维码生成
- asp.net mvc 未找到路径“/favicon.ico”的控制器或该控制器未实现 IController
- asp.net TreeView递归循环子节点生成树形菜单实例
- asp.net实现上传图片时判断图片的模式GRB或CMYK的方法
- asp.net简单页面控件赋值实现方法
- asp.net core + angular2
- WCF 无法激活服务,因为它不支持 ASP.NET 兼容性。已为此应用程序启用了 ASP.NET 兼容性
- asp.net实现的MD5加密和DES加解密算法类完整示例
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(二)-- Web Api Demo
- ASP.Net 后台代码更改 前台控件class
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(七)-- 结构化配置
- ASP.NET MVC 教程汇总
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-通知(Advice)API
- Custom WEB Service (ASP.NET)AAD验证登录
- ASP.NET输出JSON格式数据