c# 中间件简说

一、什么是中间件

中间件是一种装配到应用管道以处理请求和响应的软件。是介于request与response处理过程之间的一个插件(一道处理过程),相对比较轻量级,并且在全局上会影响到request对象和response对象的属性。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。每个组件:

1、选择是否将请求传递到管道中的下一个组件。

2、可在管道中的下一个组件前后执行工作。

原理图:

多个中间件时,中间件请求和响应的中间件顺序相反

二、为什么使用中间件

在我们很多时候,当一个请求过来之后,我们想对这个请求做各种各样的操作和记录,这个时候我们可以加入中间件。目的就是对这个请求和响应做处理,其实不难理解,这就是类似于工业机器,一个商品出来之前会有很多关卡,会执行N到工序。最后加工出来的产品就是我们想要的,也是安全的。这些关卡就类似于中间件的作用了。

微软约定中间件需要两个参数,一个是httpcontext上下文对象,一个是Task类型的委托。通过上下文对象,处理请求,通过委托传递上下文对象到下一个中间件。核心就是一系列的请求委托,Run、Use、Map

  • Run:是最后一道工序,管道末尾。
  • Use:连接请求委托,next 向下走。
  • Map:扩展用作约定创建管道分支。

三、定义中间件

中间件的处理流程就像一个俄罗斯套娃,微软约定中间件需要两个参数,一个是httpcontext上下文对象,一个是Task类型的委托。通过上下文对象,处理请求,通过委托传递上下文对象到下一个中间件,这也是套娃模式的由来。RequestDelegate是管道的核心。ApplicationBuilder就是接收了很多个RequestDelegae把它拼到一起。

public class TestMiddleware

{

/// <summary>

/// App授权配置信息

/// </summary>

internal TestDomain confDomain;

/// <summary>

/// 请求处理Request日志任务的 委托

/// </summary>

private readonly RequestDelegate _next;

/// <summary>

/// 构造函数 只会初始化一次

/// </summary>

/// <remarks>

/// <para/>Author : hyy

/// <para/>Date : 2022-12-07 23:031

/// </remarks>

/// <param name="next">构建</param>

/// <param name="authConfig">配置参数</param>

public TestMiddleware(RequestDelegate next, TestDomain authConfig)

{

LogHelper.Info("TestMiddleware 初始化");

_next = next;

confDomain = authConfig;

}

/// <summary>

/// 中间件调用函数

/// </summary>

/// <remarks>

/// <para/>Date : 2022-12-07

/// <para/>Author : HUYOUYANG

/// </remarks>

/// <param name="context">当前上下文HttpContext对象</param>

/// <returns></returns>

public async Task Invoke(HttpContext context)

{

LogHelper.Info("TestMiddleware request");

///调用之前

await _next(context);

// 调用之后

LogHelper.Info("TestMiddleware result");

}

定义

封装拓展方法

创建一个中间件拓展类,为每个自定义中间件创建方法,通过IApplicationBuilder拓展方法暴露

我这里定义了三个相同的只是日志文本不同的中间件

/// <summary>

/// UseTestMiddleware

/// </summary>

/// <remarks>

/// <para/>Author : hyy

/// <para/>Date : 2023-12-08 10:05

/// </remarks>

/// <param name="builder">builder</param>

/// <param name="authConfig">参数</param>

/// <returns>builder</returns>

public static IApplicationBuilder UseTestMiddleware(this IApplicationBuilder builder, TestDomain authConfig)

{

return builder.UseMiddleware<TestMiddleware>(authConfig);

}

/// <summary>

/// UseTestMiddleware

/// </summary>

/// <remarks>

/// <para/>Author : hyy

/// <para/>Date : 2023-12-08 10:05

/// </remarks>

/// <param name="builder">builder</param>

/// <param name="authConfig">参数</param>

/// <returns>builder</returns>

public static IApplicationBuilder UseTest1Middleware(this IApplicationBuilder builder, TestDomain authConfig)

{

return builder.UseMiddleware<Test1Middleware>(authConfig);

}

/// <summary>

/// UseTestMiddleware

/// </summary>

/// <remarks>

/// <para/>Author : hyy

/// <para/>Date : 2023-12-08 10:05

/// </remarks>

/// <param name="builder">builder</param>

/// <param name="authConfig">参数</param>

/// <returns>builder</returns>

public static IApplicationBuilder UseTest2Middleware(this IApplicationBuilder builder, TestDomain authConfig)

{

return builder.UseMiddleware<Test2Middleware>(authConfig);

}

四、配置使用中间件

使用中间件

**注意:**使用中间件,顺序非常重要。比如此处,要放在权限处理的前面。不然请求从管道回来的时候,会先走消息处理,然后再判断权限,这样的话就无法处理了。因为使用多个中间件时,中间件请求和响应的顺序是相反的,此处还是爬楼看上面的原理图比较清晰。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

{

if (env.IsDevelopment())

{

app.UseDeveloperExceptionPage();

}

else

{

app.UseExceptionHandler("/Error");

}

// HYY

app.UseTestMiddleware(Configuration.GetSection("TestDomain").Get<TestDomain>());

app.UseTest1Middleware(Configuration.GetSection("TestDomain").Get<TestDomain>());

app.UseTest2Middleware(Configuration.GetSection("TestDomain").Get<TestDomain>());

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>

{

endpoints.MapRazorPages();

});

}

五、演示

定义测试Http接口:

Http请求测试:

相关推荐
qq_537562674 分钟前
跨语言调用C++接口
开发语言·c++·算法
wjs202414 分钟前
DOM CDATA
开发语言
Tingjct16 分钟前
【初阶数据结构-二叉树】
c语言·开发语言·数据结构·算法
猷咪42 分钟前
C++基础
开发语言·c++
IT·小灰灰44 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧1 小时前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q1 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳01 小时前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾1 小时前
php 对接deepseek
android·开发语言·php
2601_949868361 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter