【问题标题】:Unable to read request body from HttpContext on asp.net core api deployed on Lambda无法从部署在 Lambda 上的 asp.net 核心 api 上的 HttpContext 读取请求正文
【发布时间】:2019-12-06 16:43:36
【问题描述】:

我有一个当前托管在 IIS 上的 asp.net core wed api,我正在尝试将其迁移到 AWS Lambda。

对于这个 api,我编写了一个日志中间件,它记录所有传入的请求及其各自的响应。中间件InvokeAsync方法的代码如下(仅相关部分)

public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            var request = context.Request;

            var requestTime = DateTime.UtcNow;
            var requestBodyContent = await ReadRequestBody(request);
            var originalBodyStream = context.Response.Body;
            using (var responseBody = new MemoryStream())
            {
                var response = context.Response;
                //The context.Response.Body memory stream cannot be read from more than once. If we read it here to log it the response to the client will be empty 
                //Instead we have all subsequent middleware write to the temporary responseBody memory stream which we can later read from
                response.Body = responseBody;

                //calculate the duration of the call
                Stopwatch callDurationTimer = new Stopwatch();
                callDurationTimer.Start();
                await next(context);
                callDurationTimer.Stop();

                string responseBodyContent = null;
                responseBodyContent = await ReadResponseBody(response);

                //we write the contents of the temporary response memory stream to the original response memory stream in order to return the correct response. 
                await responseBody.CopyToAsync(originalBodyStream);
                /* 
                   code that logs to a DB
                */
            }
        }
        catch (Exception e)
        {
            logger.LogError(e, "Logging Middleware Error");
            await next(context);
        }
    }

以及 ReadRequestBody 函数的代码

 private async Task<string> ReadRequestBody(HttpRequest request)
    {
        request.EnableRewind();            

        var buffer = new byte[Convert.ToInt32(request.ContentLength)];
        await request.Body.ReadAsync(buffer, 0, buffer.Length);
        var bodyAsText = Encoding.UTF8.GetString(buffer);
        request.Body.Seek(0, SeekOrigin.Begin);

        bodyAsText = Regex.Replace(bodyAsText, @"\s+", "");
        return bodyAsText;
    }

以上代码在 IIS 托管方案中按预期工作。

在 Lambda 场景中,我遇到以下问题:尝试读取请求正文一无所获。 ReadRequestBodyFunction 的结果是一个空字符串。其他一切正常。日志记录和系统的其余部分。

在将请求交给我的 api 之前,有人知道 Lambda 对请求做了什么,导致请求正文不可读吗?

如果这很重要,我使用的是 asp.net core 2.2,并且该应用程序是自包含的,因此它可以在仅支持本机 .net core 2.1 的 Lambda 上运行。

【问题讨论】:

    标签: asp.net-core aws-lambda httpcontext


    【解决方案1】:

    我通过查看 Amazon.Lambda.AspNetCoreServer 包代码 (v4.0.0) 找到了解决方案。 在某些时候,当他们编组请求时,他们会将请求的主体设置为 MemoryStream。这似乎以某种方式与 request.ContentLength 属性混淆,在这行代码中该属性始终为空 var buffer = new byte[Convert.ToInt32(request.ContentLength)];

    request.Body.Length 属性按预期工作。所以将上面的行更改为 var buffer = new byte[Convert.ToInt32(request.Body.Length)];

    解决了问题。

    【讨论】:

      猜你喜欢
      • 2018-10-25
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 2019-02-17
      • 2015-10-26
      • 1970-01-01
      • 2017-03-22
      相关资源
      最近更新 更多