我需要在每个.MapGet()之后以相同的方式操作JSON(应用一些转换).

我一直认为,我们可以在响应管道和请求管道上设置中间件,方法是在.MapGet()之后放置.UseMiddleware()(或.Use()),如下所示:

[...]
app.UseMiddleware<MyRequestMiddleware>(); //It should be invoked before .MapGet()
app.MapGet(...);
app.UseMiddleware<MyResponseMiddleware>(); //It should be invoked after .MapGet()
await app.RunAsync();

实际上,MyRequestMiddlewareMyResponseMiddleware都是在.MapGet()之前运行的流水线.如何实现"响应管道", for each 端点运行一些转换函数?我知道我可以创建注入DI的服务并调用每个端点中的转换,但我不想更改.MapGet()个实现并将转换分离在另一个层中.

推荐答案

在ASP.NET中,以前运行的核心中间件也在之后运行(在某种程度上).请求处理流水线是以较早的中间件(可选的)调用下一个(docs)的方式构建的.

enter image description here

因此,如果你想要一个中间件,它在下一个中间件之后做一些事情,那么你只需按以下方式实现它:

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        await _next(context);

        // your code that runs after the following middleware
    }
}

app.Use(async (context, next) =>
{
    await next(context);
    // your code that runs after the following middleware
});

在此模式中,您可以编写单个中间件来执行之前和之后的操作.

app.MapGet(...)不注册中间件,它注册路由处理器.如果我没记错的话,处理路由的中间件注册为UseRouting(也不需要显式调用它).

另请参见How do I get the incoming request body and the outgoing response body in ASP.NET Core middleware?.

Csharp相关问答推荐

使用ElasticsearchClient设置忽略属性.默认MappingFor<>

如何从C#中有类.x和类.y的类列表中映射List(字符串x,字符串y)?

无法将blob发送到Azure -缺少HTTP标头异常

Serilog SQL服务器接收器使用UTC作为时间戳

Unity如何在PlayerPrefs中保存数据?

使用LayoutKind在C#中嵌套 struct .显式

将轮询与超时同步

为什么我的表单在绑定到对象时提交空值?

从.Net 6 DLL注册和检索COM对象(Typelib导出:类型库未注册.(异常来自HRESULT:0x80131165))

在EF Core中,有没有什么方法可以防止在查询中写入相同的条件,而代之以表达式?

我的MRG32k3a算法实现返回的数字超出了预期的[0,1]范围

是否可以将Collectionview中的数组与ObservableCollection绑定?

如何允许数组接受多个类型?

在集成测试中可以在模拟InMemory数据库中设定数据种子

为什么在使用JsonDerivedType序列化泛型时缺少$type?

毛伊岛.NET 8图片不再适合按钮

ASP.NET核心中的授权,如何在DbContext启动之前提供租用ID

使用C#代码和SQL SERVER中的相同证书签名会产生不同的结果

客户端/服务器RPC如何处理全局变量?

这是T自身的布尔表达式是什么意思?