这节演示一下自定义中间件,第一节我们讲到,中间件的处理流程就像一个俄罗斯套娃,那这种俄罗斯套娃型的流程内部是如何实现的呢,下面请看代码​。

​第一种写法是直接写在Configure方法中的,使用app.Use(委托)配合lambda表达式使用,适合很轻量级的中间件。​

app.Use(async (context, next) =>
{
await context.Response.WriteAsync("CustomerMiddleWare1-in\n");
await next();
await context.Response.WriteAsync("CustomerMiddleWare1-out");
});

​微软约定中间件需要两个参数,一个是httpcontext上下文对象,一个是Task类型的委托​。通过上下文对象,处理请求,通过委托​传递上下文对象到下一个中间件(这也是套娃模式的由来)。

​这也限制了方法,必须是异步的async方法,调用next()之后,上下文对象发送给下一中间件了,该方法就会处于等待状态,直到后续的中间件处理完毕,返回后,再执行next()方法之后的代码​。(关于同步和异步的有关知识,将在后续进行讲解)

​除了使用Use()方法,还有一种用法,这个方法有点特殊,因为它不存在next()方法传递上下文对象,它是请求管道的底,用于直接返回响应

//run 是终端中间件,他是没有next()方法的,只要进入这个中间件,后续的中间件都不会执行了,从它这里请求完毕原路返回
app.Run(async context =>
{
await context.Response.WriteAsync("I am End MiddleWare\n");
});

​.NetCore 3.x推出了一个新的中间件,叫EndPoints

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});

​它跟Run()一样,是兜底的中间件,但是用法比较特殊了,微软给我们的默认配置就是直接路由到某一页面,一般是网站首页​。

下面看一下运行结果的演示,有如下三个中间件:

 //use是添加中间中间件,就是处理完了,继续传给下一个中间件,它有next()委托
app.Use(async (context, next) =>
{
  await context.Response.WriteAsync("CustomerMiddleWare1-in\n");
  await next();
  await context.Response.WriteAsync("CustomerMiddleWare1-out");
});
app.Use(async (context, next) =>
{
  await context.Response.WriteAsync("CustomerMiddleWare2-in\n");
  await next();
  await context.Response.WriteAsync("CustomerMiddleWare2-out\n");
});
//run 是终端中间件,他是没有next()方法的,只要进入这个中间件,后续的中间件都不会执行了,从它这里请求完毕原路返回
app.Run(async context =>
{
  await context.Response.WriteAsync("I am End MiddleWare\n");
});

运行结果为:

这很直观的反应了中间件的顺序执行,以及嵌套执行

下面看一下如何定义一个真正的自定义中间件

首先,我们要明确,微软规定的自定义中间件的要求

1.具有类型为RequestDelegate参数的公共构造函数,这个参数就是请求委托,它在一个个的中间件中传递

2.具有Invoke或者InvokeAsync的方法,该方法的返回值必须是Task,而且第一个参数必须是HttpContext

 public class MyMiddleWare
{
private readonly RequestDelegate _next; public MyMiddleWare( RequestDelegate next )
{
_next = next;
} public async Task InvokeAsync(HttpContext context)
{
//此处写中间件业务逻辑
//然后调用next指向下一个中间件
//调用next之前,属于请求部分的处理
await _next(context);
//next执行完毕之后,属于相应部分的处理
}
}

​定义完成以后,使用UseMiddleware<中间件>()将自定义中间件添加进来

app.UseMiddleware<MyMiddleWare>();

​但这样的用法,还是少了一点优雅与灵活性,我们可以通过扩展方法的形式,为IApplicationBuilder添加扩展方法,实现自定义中间件添加与配置的灵活应用(扩展方法在之前的文章中有讲)​

public static class MyMiddleWareExtension
{
public static IApplicationBuilder UseMymiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<MyMiddleWare>();
}
}

这样的话,就可以直接调用方法添加中间件了

 //使用扩展方法的形式,添加自定义中间件然后可以通过构造方法的形式,传递配置参数
app.UseMymiddleware();

初学者可对此做初步了解,对其中设计的代码语法知识,是必须要掌握的。另外,如果需要查看ASP.NetCore的源码,请访问https://github.com/dotnet/aspnetcore自行下载或克隆到本地

 这是我公众号二维码,最新的文章会同步至此

Asp.NetCore 自定义中间件的更多相关文章

  1. ASP.NET Core 1.1 静态文件、路由、自定义中间件、身份验证简介

    概述 之前写过一篇关于<ASP.NET Core 1.0 静态文件.路由.自定义中间件.身份验证简介>的文章,主要介绍了ASP.NET Core中StaticFile.Middleware ...

  2. ASP.NET Core 中间件自定义全局异常处理

    目录 背景 ASP.NET Core过滤器(Filter) ASP.NET Core 中间件(Middleware) 自定义全局异常处理 .Net Core中使用ExceptionFilter .Ne ...

  3. 跟我一起学.NetCore之中间件(Middleware)应用和自定义

    前言 Asp.NetCore中的请求管道是通过一系列的中间件组成的,使得请求会根据需求进行对应的过滤和加工处理.在平时开发中会时常引用别人定义好的中间件,只需简单进行app.Usexxx就能完成中间件 ...

  4. Asp.NetCore Web应用程序中的请求管道和中间件

    你是否会迷惑当我们请求一个ASP.NetWeb应用程序以后,它是怎么处理这些请求的,后台是怎么工作的,今天就讲一下Asp.NetCore Web应用程序中的请求处理过程. 上一节,我们讲到,Start ...

  5. ASP.NET Core 1.0 静态文件、路由、自定义中间件、身份验证简介

    概述 ASP.NET Core 1.0是ASP.NET的一个重要的重新设计. 例如,在ASP.NET Core中,使用Middleware编写请求管道. ASP.NET Core中间件对HttpCon ...

  6. asp.net core中写入自定义中间件

    首先要明确什么是中间件?微软官方解释:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?tabs=aspnet ...

  7. 如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容?

    原文:如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容? 文章名称: 如何在ASP.NET Core自定义中间件读取Request.Body和 ...

  8. Asp.Net Core入门之自定义中间件

    什么是中间件? 这里引用官方解释: 中间件是用于组成应用程序管道来处理请求和响应的组件.管道内的每一个组件都可以选择是否将请求交给下一个组件.并在管道中调用下一个组件之前和之后执行某些操作.请求委托被 ...

  9. asp.net core 3.1 自定义中间件实现jwt token认证

    asp.net core 3.1 自定义中间件实现jwt token认证 话不多讲,也不知道咋讲!直接上代码 认证信息承载对象[user] /// <summary> /// 认证用户信息 ...

随机推荐

  1. 2019HDU多校第七场 HDU6656 Kejin Player H 【期望递归】

    一.题目 Kejin Player H 二.分析 因为在当前等级$i$,如果升级失败可能会退回到原来的某一等级$x$,相当于就是失败的期望就是$E + (Sum[i-1] - Sum[x-1]) + ...

  2. ResNet的个人总结

    ResNet可以说是我认真读过的第一篇paper,据师兄说读起来比较简单,没有复杂的数学公式,不过作为经典的网络结构还是有很多细节值得深究的.因为平时不太读英文文献,所以其实读的时候也有很多地方不是很 ...

  3. 【博弈论】组合游戏及SG函数浅析

    目录 预备知识 普通的Nim游戏 SG函数 预备知识 公平组合游戏(ICG) 若一个游戏满足: 由两名玩家交替行动: 游戏中任意时刻,合法操作集合只取决于这个局面本身: 若轮到某位选手时,若该选手无合 ...

  4. 攻防世界 reverse 进阶 8-The_Maya_Society Hack.lu-2017

    8.The_Maya_Society Hack.lu-2017 在linux下将时间调整为2012-12-21,运行即可得到flag. 下面进行分析 1 signed __int64 __fastca ...

  5. 在ASP.NET Core中用HttpClient(四)——提高性能和优化内存

    到目前为止,我们一直在使用字符串创建请求体,并读取响应的内容.但是我们可以通过使用流提高性能和优化内存.因此,在本文中,我们将学习如何在请求和响应中使用HttpClient流. 什么是流 流是以文件. ...

  6. 冒泡排序(BubbleSort)

    介绍: 冒泡排序是一种最基础的交换排序(两两比较待排序的关键字,交换不满足次序要求的那对数,直到整个表都满足次序要求为止),工作方式如同碳酸饮料中的二氧化碳气泡最终会上浮到顶端一样,故名"冒 ...

  7. PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 目录 PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) ...

  8. angularjs 图片上传

    <input type="file" file-model="myFile"/><div class="col-md-12" ...

  9. [Fundamental of Power Electronics]-PART I-2.稳态变换器原理分析-2.1 引言

    2.1 引言 在上一章中,介绍了降压变换器作为降低直流电压的一种方法,其仅使用非耗散开关,电感器和电容器.开关状态变换产生一个矩形波形\(v_{s}(t)\),如图2.1所示.当开关位于位置1时,该电 ...

  10. java正则匹配${xxx} 排除单引号双引号内的内容,前提引号必须成对出现

    public static void main(String[] a) { String wpp = "select 1, ${mark} '``this is, `/message22` ...