Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.net核心API中间件管道中,HttpResponse何时被发送到客户端?_C#_Http_Asp.net Core_.net Core_Asp.net Core 2.1 - Fatal编程技术网

C# 在.net核心API中间件管道中,HttpResponse何时被发送到客户端?

C# 在.net核心API中间件管道中,HttpResponse何时被发送到客户端?,c#,http,asp.net-core,.net-core,asp.net-core-2.1,C#,Http,Asp.net Core,.net Core,Asp.net Core 2.1,我对IIS何时发回响应感到非常困惑,我真的很想知道这在引擎盖下是如何工作的,因为我正在做响应日志记录,我不想破坏身体 这是我的日志中间件调用,在MVC中间件(控制器)之前调用。响应是在控制器返回其Ok方法后立即发送还是等待中间件的其余部分?如果我这样做,是否有可能破坏响应 public async Task Invoke(HttpContext context) { var requestResponseLog = new RequestResponseLog {

我对IIS何时发回响应感到非常困惑,我真的很想知道这在引擎盖下是如何工作的,因为我正在做响应日志记录,我不想破坏身体

这是我的日志中间件调用,在MVC中间件(控制器)之前调用。响应是在控制器返回其Ok方法后立即发送还是等待中间件的其余部分?如果我这样做,是否有可能破坏响应

public async Task Invoke(HttpContext context)
{
    var requestResponseLog = new RequestResponseLog
    {
        RequestTime = DateTimeOffset.UtcNow,
        Request = await FormatRequest(context)
    };

    Stream originalBody = context.Response.Body;

    using (MemoryStream newResponseBody = _recyclableMemoryStreamManager.GetStream())
    {
        context.Response.Body = newResponseBody;

        await _next(context);

        newResponseBody.Seek(0, SeekOrigin.Begin);
        await newResponseBody.CopyToAsync(originalBody);

        newResponseBody.Seek(0, SeekOrigin.Begin);

        requestResponseLog.ResponseTime = DateTimeOffset.UtcNow;
        requestResponseLog.Response = await FormatResponse(context, newResponseBody);

        _requestResponseHandler(requestResponseLog);
    }
}

将每个注册的中间件看作是创建请求的一个步骤。您的invoke方法是该路径上的“您的”步骤。
wait\u next(上下文)
指示框架在此时转移到管道中的下一个中间件上,但在其余中间件执行后返回,以便可以再次提取代码

所以。。考虑到这一点,让我们假设我们设置了3个中间件。管道的工作原理如下:

[请求进来]

中间件-1=>中间件-2=>中间件-3

[产生响应]

中间件-3=>中间件-2=>中间件-1

[响应发送到呼叫方]

假设您在Middleware2的Invoke方法中添加了
wait\u next(上下文)
。当代码到达该点时,它会跳转到管道中的下一个中间件上,但当它返回响应时,它知道在那里停止。所以你可以再次拦截它

如果您正在记录一个请求,您的自定义代码将在该
wait\u next(上下文)
调用之前执行。如果您正在记录响应,它将在该调用之后出现


注意:此外,中间件的顺序取决于它们在启动类中注册的顺序。

嗨,Robert,谢谢你的回复,我理解,但是:有些人告诉我,响应在写入响应后会立即发送给调用方。它们可能是正确的,也可能是错误的。这取决于您计划如何处理请求。如果您想更改发送回客户机的响应,这是一个稍微不同的问题。因为,一旦创建响应,尝试编辑响应将导致问题。