ASP.NET Core 2 学习笔记(三)中间件
之前ASP.NET中使用的HTTP Modules及HTTP Handlers,在ASP.NET Core中已不复存在,取而代之的是Middleware。Middleware除了简化了HTTP Modules/Handlers的使用方式,还带入了Pipeline的概念。
本篇将介绍ASP.NET Core的Middleware概念及用法。
Middleware 概念
ASP.NET Core在Middleware的官方说明中,使用了Pipeline这个名词,意指Middleware像水管一样可以串联在一起,所有的Request及Response都会层层经过这些水管。
用图例可以很容易理解,如下图:
App.Use
Middleware的注册方式是在Startup.cs的Configure
对IApplicationBuilder
使用Use
方法注册。
大部分扩展的Middleware也都是以Use开头的方法注册,例如:
- UseMvc():MVC的Middleware
- UseRewriter():URL rewriting的Middleware
一个简单的Middleware 范例。如下:
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;namespace MyWebsite
{public class Startup{// This method gets called by the runtime. Use this method to add services to the container.// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940public void ConfigureServices(IServiceCollection services){}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.Use(async (context, next) =>{await context.Response.WriteAsync("First Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("First Middleware out. \r\n");});app.Use(async (context, next) =>{await context.Response.WriteAsync("Second Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("Second Middleware out. \r\n");});app.Use(async (context, next) =>{await context.Response.WriteAsync("Third Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("Third Middleware out. \r\n");});app.Run(async (context) =>{await context.Response.WriteAsync("Hello World! \r\n");});}}
}
用浏览器打开网站任意连结,输出结果:
First Middleware in. Second Middleware in. Third Middleware in. Hello World! Third Middleware out. Second Middleware out. First Middleware out.
在Pipeline的概念中,注册顺序是很重要的事情。请求经过的顺序一定是先进后出。
Request 流程如下图:
Middleware 也可以作为拦截使用,如下:
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;namespace MyWebsite
{public class Startup{// This method gets called by the runtime. Use this method to add services to the container.// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940public void ConfigureServices(IServiceCollection services){}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.Use(async (context, next) =>{await context.Response.WriteAsync("First Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("First Middleware out. \r\n");});app.Use(async (context, next) =>{await context.Response.WriteAsync("Second Middleware in. \r\n");// 水管阻塞,封包不往后送var condition = false;if (condition){await next.Invoke();}await context.Response.WriteAsync("Second Middleware out. \r\n");});app.Use(async (context, next) =>{await context.Response.WriteAsync("Third Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("Third Middleware out. \r\n");});app.Run(async (context) =>{await context.Response.WriteAsync("Hello World! \r\n");});}}
}
输出结果:
First Middleware in. Second Middleware in. Second Middleware out. First Middleware out.
在Second Middleware 中,因为没有达成条件,所以封包也就不在往后面的水管传送。流程如图:
App.Run
Run
是Middleware的最后一个行为,以上面图例来说,就是最末端的Action。
它不像Use
能串联其他Middleware,但Run
还是能完整的使用Request及Response。
App.Map
Map
是能用来处理一些简单路由的Middleware,可依照不同的URL指向不同的Run
及注册不同的Use
。
新增一个路由如下:
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;namespace MyWebsite
{public class Startup{// This method gets called by the runtime. Use this method to add services to the container.// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940public void ConfigureServices(IServiceCollection services){}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.Use(async (context, next) =>{await context.Response.WriteAsync("First Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("First Middleware out. \r\n");});// app.Use(async (context, next) =>// {// await context.Response.WriteAsync("Second Middleware in. \r\n");// // 水管阻塞,封包不往后送// var condition = false;// if (condition)// {// await next.Invoke();// }// await context.Response.WriteAsync("Second Middleware out. \r\n");// });app.Map("/second", mapApp =>{mapApp.Use(async (context, next) =>{await context.Response.WriteAsync("Second Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("Second Middleware out. \r\n");});mapApp.Run(async context =>{await context.Response.WriteAsync("Second. \r\n");});});app.Use(async (context, next) =>{await context.Response.WriteAsync("Third Middleware in. \r\n");await next.Invoke();await context.Response.WriteAsync("Third Middleware out. \r\n");});app.Run(async (context) =>{await context.Response.WriteAsync("Hello World! \r\n");});}}
}
开启网站任意连结,会显示:
First Middleware in. Third Middleware in. Hello World! Third Middleware out. First Middleware out.
开启网站http://localhost:5000/second
,则会显示:
First Middleware in. Second Middleware in. Second. Second Middleware out. First Middleware out.
创建Middleware 类
如果Middleware全部都写在Startup.cs,代码将很难维护,所以应该把自定义的Middleware逻辑独立出来。
建立Middleware类不需要额外继承其它类或接口,一般的类即可,例子如下:
FirstMiddleware.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;namespace MyWebsite
{public class FirstMiddleware{private readonly RequestDelegate _next;public FirstMiddleware(RequestDelegate next){_next = next;}public async Task Invoke(HttpContext context){await context.Response.WriteAsync($"{nameof(FirstMiddleware)} in. \r\n");await _next(context);await context.Response.WriteAsync($"{nameof(FirstMiddleware)} out. \r\n");}}
}
全局注册
在Startup.Configure
注册Middleware就可以套用到所有的Request。如下:
Startup.cs
// ...
public class Startup
{// ...public void Configure(IApplicationBuilder app){app.UseMiddleware<FirstMiddleware>();// ...}
}
局部注册
Middleware 也可以只套用在特定的Controller 或Action。注册方式如下:
Controllers\HomeController.cs
// ..
[MiddlewareFilter(typeof(FirstMiddleware))]
public class HomeController : Controller
{// ...[MiddlewareFilter(typeof(SecondMiddleware))]public IActionResult Index(){// ...}
}
Extensions
大部分扩展的Middleware都会用一个静态方法包装,如:UseMvc()
、UseRewriter()
等。
自定义的Middleware当然也可以透过静态方法包,范例如下:
Extensions\CustomMiddlewareExtensions.cs
using Microsoft.AspNetCore.Builder;namespace MyWebsite
{public static class CustomMiddlewareExtensions{public static IApplicationBuilder UseFirstMiddleware(this IApplicationBuilder builder){return builder.UseMiddleware<FirstMiddleware>();}}
}
注册Extension Middleware 的方式如下:
Startup.cs
// ...
public class Startup
{// ...public void Configure(IApplicationBuilder app){app.UseFirstMiddleware();// ...}
}
参考
ASP.NET Core Middleware Fundamentals
Creating Custom Middleware In ASP.Net Core
老司机发车啦:https://github.com/SnailDev/SnailDev.NETCore2Learning
ASP.NET Core 2 学习笔记(三)中间件相关推荐
- asp.net core webAPI学习笔记(三)资源请求
IDE 版本:Visual Studio 2017 15.9.7 asp.net core 版本 2.1.1 本文档说明需在 asp.net core webAPI学习笔记(一)项目搭建 的基础下进行 ...
- ASP.NET Core 2 学习笔记(七)路由
ASP.NET Core通过路由(Routing)设定,将定义的URL规则找到相对应行为:当使用者Request的URL满足特定规则条件时,则自动对应到相符合的行为处理.从ASP.NET就已经存在的架 ...
- ASP.NET Core 2 学习笔记(四)依赖注入
原文:ASP.NET Core 2 学习笔记(四)依赖注入 ASP.NET Core使用了大量的依赖注入(Dependency Injection, DI),把控制反转(Inversion Of Co ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(二)-- Web Api Demo
在上一篇里,我已经建立了一个简单的Web-Demo应用程序.这一篇将记录将此Demo程序改造成一个Web Api应用程序. 一.添加ASP.NET Core MVC包 1. 在project.json ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(一)-- 起步
一.安装Visual Studio Code 安装文件下载地址:VS Code,当前最新版本是1.3. 推荐安装最新版,因为附带Debug插件,支持在vs code上进行断点调试. 二.安装.Net ...
- 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面
原文:学习ASP.NET Core Razor 编程系列三--创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 ...
- ASP.NET MVC 2 学习笔记二: 表单的灵活提交
ASP.NET MVC 2 学习笔记二: 表单的灵活提交 前面说到有做到公司内部的一个请假系统,用的是ASP.NET MVC 2+Entity Framework.虽然EF(Entity Frame ...
- Core Data 学习笔记(二)被管理对象模型
为什么80%的码农都做不了架构师?>>> 目录 Core Data 学习笔记(一)框架简介 Core Data 学习笔记(二)被管理对象模型 Core Data 学习笔记(三) ...
- K8S 学习笔记三 核心技术 Helm nfs prometheus grafana 高可用集群部署 容器部署流程
K8S 学习笔记三 核心技术 2.13 Helm 2.13.1 Helm 引入 2.13.2 使用 Helm 可以解决哪些问题 2.13.3 Helm 概述 2.13.4 Helm 的 3 个重要概念 ...
最新文章
- 修改mac系统的host文件 (一)
- C#教程8:面向对象编程【01】
- ionic overflow:auto失效
- 如何使用js动态显示或隐藏DIV
- 无光驱如何修复W7计算机,Win7电脑没有光驱怎么装系统?
- Java8————Base64
- 【Java】Socket实现的C/S模式半UI多人聊天程序
- Mac brew报错Error: The following directories are not writable by your user: /usr/local/share/man/man5
- ceph 代码分析 读_五大常见存储系统PK | Ceph、GlusterFS、MooseFS、HDFS、DRBD
- redis双写一致性问题
- ArcMap怎么导出shape文件到奥维互动地图
- 数据库变为可疑_SQL数据库可疑解决方法
- comps电磁场模拟软件_电力系统仿真软件综述说课.ppt
- UrlRewrite的使用
- js转换金钱为中文单位元、万元、亿元、万亿
- 关于Python爬取热搜的另一种方法
- CSS面试须知--盒子模型、浮动及定位
- notion自建服务器,【速报】Notion的特色「双向链接」方案来了,Synced Block 登场...
- 香港喜运佳,承载着太多的回忆
- 奋斗吧,程序员——第二十四章 想佳人、妆楼凝望,误几回、天际识归舟
热门文章
- springboot中使用redis详解
- 类型多种_五轴机床有很多种类型,你知道几种?
- python 函数调用 不允许关键字参数_你所不知道的Python|函数参数的演进之路
- java中间缓存变量机制_Java中间缓存变量机制
- kali怎么新建文本_甘特图怎么画?零基础快速绘制甘特图的软件
- 信息论与编码_哈夫曼编码
- linux tracepoint例子,tracepoint介绍
- android自定义下载框架,Android_DownloadUtil
- wps怎么投递简历发到boss直聘_BOSS直聘情色招聘:洗脑传销广告漫天飞,还陷虚假招聘...
- yolov3 推理所需要的时间_目标检测-番外五:YOLOv3-Plus