C# 为什么可以';在';之后,是否更改HTP响应;下一个';呼叫

C# 为什么可以';在';之后,是否更改HTP响应;下一个';呼叫,c#,asp.net,middleware,C#,Asp.net,Middleware,结果响应只有“Before!After!”,但缺少“helloworld!”。为什么会这样 发言人说: 避免在调用next之后修改HttpResponse,管道中的下一个组件可能已写入响应,导致将其发送到客户端 我不明白“将其发送到客户端”是什么意思。通过调用next,您将控制权传递给链中的下一个中间件,这意味着当前中间件失去控制,进一步的中间件可能已写入响应,刷新响应,甚至关闭流 “使其发送到客户端”意味着进一步的中间件之一可能已经做了一些事情,如上面的选项,以使响应从服务器发送到调用它的任何

结果响应只有“Before!After!”,但缺少“helloworld!”。为什么会这样

发言人说:

避免在调用next之后修改HttpResponse,管道中的下一个组件可能已写入响应,导致将其发送到客户端


我不明白“将其发送到客户端”是什么意思。

通过调用next,您将控制权传递给链中的下一个中间件,这意味着当前中间件失去控制,进一步的中间件可能已写入响应,刷新响应,甚至关闭流


“使其发送到客户端”意味着进一步的中间件之一可能已经做了一些事情,如上面的选项,以使响应从服务器发送到调用它的任何客户端。正如您的代码所证明的那样,这并不能保证会发生,但这是可能的。因此,建议在调用next之后写入httpresponse以防万一。

我发现原因是如果
app.Map
与请求匹配,则不会将
app.Run
插入管道。这对我来说是非常意外的。

但在我的例子中,被忽略的是“下一个”调用中写入的内容,而不是在此之后所做的更改(即“之后!”),这不应该是由下一个调用写入响应或关闭流引起的。实际上。。。你是对的。我的问题是由其他原因引起的。我发现如果
映射
与请求匹配,那么
运行
将不会插入管道。
public void Configure(IApplicationBuilder app) {
    app.Map("/hahaha", HandleMapTest);
    app.Run(async (context) => {
        await context.Response.WriteAsync("Hello World!");
    });
}

public static void HandleMapTest(IApplicationBuilder app) {
    app.Use(async (context, next) => {
        await context.Response.WriteAsync("Before!");
        await next.Invoke();
        await context.Response.WriteAsync("After!");
    });
}