【问题标题】:Unable to send modified HttpResponse back to Response.Body无法将修改后的 HttpResponse 发送回 Response.Body
【发布时间】:2020-09-01 09:08:39
【问题描述】:

我正在使用 ASP.NET Core 2.1 中的中间件创建一个代理,它使第 3 方 API(OData 端点)调用

  1. 获取数据
  2. 做一些改变
  3. 向 Response.Body 发送响应

    我参考了here

    下面是代码 sn-p,无论我从 API 获得什么响应,它都能正常工作,我将进一步发送它
using (var responseMessage = await _httpClient.SendAsync(targetRequestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
                    {
                        context.Response.StatusCode = (int)responseMessage.StatusCode;
                        CopyFromTargetResponseHeaders(context, responseMessage);                   
                        await responseMessage.Content.CopyToAsync(context.Response.Body);
                    }

但是,如果我在这里修改响应,例如,像这样,它就不起作用并且它显示空白页面而没有任何错误。

using (var responseMessage = await _httpClient.SendAsync(targetRequestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
                {
                    context.Response.StatusCode = (int)responseMessage.StatusCode;
                    CopyFromTargetResponseHeaders(context, responseMessage);
                    var output = new StringContent("some sample string or may be JSON", Encoding.UTF8, "application/json");
                    await output.CopyToAsync(context.Response.Body);
                }

看起来我们不允许对从 API 调用收到的响应进行任何更改。谁能告诉我如何将修改后的内容发送回 Response.Body?

【问题讨论】:

  • 我无法使用example 和您对响应的修改来重现您的问题。
  • 很奇怪,我在浏览器上看到我的回复为空白,Chrome 显示“无法获得任何回复”。
  • 在我的例子中,响应以 JSON 格式出现。对于 text/html,它可以工作,但不适用于 application/json。在您的工作示例中,如果响应的内容类型不是“文本”或“Javascript”,您将按原样返回响应。

标签: asp.net-core odata asp.net-core-webapi


【解决方案1】:

您可能会遇到System.InvalidOperationException: Response Content-Length mismatch: too few bytes written 或类似的异常(您应该在Output window 中看到)。所以不要使用响应中的Content-LengthContent-Type 标头,因为它们可能与您修改的内容的Content-LengthContent-Type 不匹配,例如:

private void CopyFromTargetResponseHeaders(HttpContext context, HttpResponseMessage responseMessage)
{
    ...
    foreach (var header in responseMessage.Content.Headers)
    {
        // do not use the content headers from the response because the content will be modified
        // context.Response.Headers[header.Key] = header.Value.ToArray();
    }
    ...
}

【讨论】:

    【解决方案2】:

    我可以通过在将修改后的响应呈现给 context.Response.Body 之前更新“Content-Length”响应标头来解决问题,如下所示:

    context.Response.Headers.Remove("Content-Length");
    context.Response.Headers.Add("Content-Length", modifiedResponseStream.Length.ToString());
    

    【讨论】:

      猜你喜欢
      • 2015-06-30
      • 2011-07-27
      • 1970-01-01
      • 2012-01-07
      • 2016-08-27
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      相关资源
      最近更新 更多