【问题标题】:.Net Core Bad Request Log in Middleware get request parameters.Net Core Bad Request Log in Middleware 获取请求参数
【发布时间】:2021-06-29 11:27:31
【问题描述】:

您好,我有一个核心 API。在 Api 中,我还想记录请求详细信息。我在下面写了代码

using InfiniteDocumentsAPI.Core.Services;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MBFSPT_OCRABBYY_InfiniteDocumentsAPI.Middlewares
{
    public class RequestLoggingMiddleware
    {
        
        private readonly RequestDelegate _next;

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

        public async Task Invoke(HttpContext context, LoggerService log)
        {
            try
            {
                await _next(context);
            }
            finally
            {
                if (context.Response?.StatusCode == 400)
                {            
                    string requestStr = "";
                    context.Request.EnableBuffering();
                    using (var reader = new StreamReader(context.Request.Body))
                    {
                        requestStr =await reader.ReadToEndAsync();
                    }
                    context.Request.Body.Position = 0;
                    log.Trace("casa", "1", "12", 0, "dasd");
                
                }                              
            }
        }     
    }
}

上面的代码没有错误。但是在 await reader.ReadToEndAsync() 调用之后 requestStr 是空字符串。我的失踪在哪里?如何获取请求正文参数?

这是 api 响应

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-b9f2fb6ba6f784439cb14fad88c2819a-9a5b8bd86b38874d-00",
  "errors": {
    "$.applicationInfo.applicationId": [
      "The JSON value could not be converted to System.Int32. Path: $.applicationInfo.applicationId | LineNumber: 0 | BytePositionInLine: 1882."
    ]
  }
}

这是请求

"applicationInfo": {
        "applicationStatusLocalText": "Submitted",
        "applicationStatusCode": "08",
        "applicationNumber": "210531-0008",
        "applicationType": "Walk-in",
        "applicationId": 42434,
        "applicationPreferredCommunicationChannelTypeCode": "Email",
        "financeGroupDesc": "Installment Finance",
        "financeGroup": "IF",
        "applicantType": "Company",
        "customerSegment": "SME",
        "applicationPurposeCode": "Corporate"
      }

从响应中我只需要错误列表。并从请求中提取一些参数,例如applicationNumber,applicationStatusLocalText

所以在日志中我想调用这段代码

log.Trace("BatchNotCreated"+stringfiedResponsesErrorList, applicationId, applicationNumber, 0, `applicationStatusLocalText`);

提前致谢

【问题讨论】:

  • 您没有收到来自服务器的响应。以下其中一项通常是错误的 1)服务器离线 2)错误的 URI 3)您使用的是 HTTPS(安全)并且 TLS 失败。
  • 我不想要响应正文。我要请求参数
  • context.Request.EnableRewind();在等待之前的尝试中,在您阅读流之前,最后可能必须倒退到 0,不完全确定
  • 核心中没有 EnableRewind。这就是我使用 EnableBuffering @arynaq 的原因
  • 你有没有试过在阅读前将体流位置设置为零?

标签: c# asp.net-core-webapi


【解决方案1】:

如下更改您的代码:

public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;
    public RequestLoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task Invoke(HttpContext context)
    {
        try
        {
            context.Request.EnableBuffering();    //add this...             
            await _next(context);
            context.Request.Body.Position = 0;    //add this...
        }
        finally
        {
            if (context.Response?.StatusCode == 400)
            {
                string applicationNumber = "";
                string requestStr = "";
                using (var reader = new StreamReader(context.Request.Body))
                {
                    requestStr = await reader.ReadToEndAsync();
                    //do your stuff....
                    var model = JObject.Parse(requestStr);
                    applicationNumber = model["applicationNumber"].ToString();
                }

                context.Request.Body.Position = 0;
            }
        }
    }
}

【讨论】:

  • 如果await _next(context);内部发生异常,则不会重置正文位置基于finally块的存在,我怀疑在任何情况下都必须读取正文。所以设置位置应该在finally块中。
猜你喜欢
  • 2019-09-27
  • 1970-01-01
  • 2016-06-20
  • 2021-03-05
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
  • 2020-05-29
  • 2013-10-02
相关资源
最近更新 更多