【问题标题】:How can I read http request body in netcore 3 more than once?如何在 net core 3 中多次读取 http 请求正文?
【发布时间】:2020-03-03 08:45:02
【问题描述】:

我有一个 netcore 3 API 应用程序,它记录传入的请求,然后将其传递给控制器​​操作。

我的代码如下所示:

public RequestLoggingHandler(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}


protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RequestLoggingRequirement requirement)
{
    try
    {
        var httpContext = _httpContextAccessor.HttpContext;
        var request = httpContext.Request;

        _repository = (ICleanupOrderRepository)httpContext.RequestServices.GetService(typeof(ICleanupOrderRepository));
        _cache = (IMemoryCache)httpContext.RequestServices.GetService(typeof(IMemoryCache));

        httpContext.Items["requestId"] = SaveRequest(request);

        context.Succeed(requirement);

        return Task.CompletedTask;
    }
    catch (Exception ex)
    {

        throw ex;
    }
}

private int SaveRequest(HttpRequest request)
{
    try
    {
        // Allows using several time the stream in ASP.Net Core
        var buffer = new byte[Convert.ToInt32(request.ContentLength)];
       request.Body.ReadAsync(buffer, 0, buffer.Length);

        var requestContent = Encoding.UTF8.GetString(buffer);
        var requestId = _repository.SaveRawHandlerRequest($"{request.Scheme} {request.Host}{request.Path} {request.QueryString} {requestContent}");

        return requestId;
    }
    catch (Exception ex)
    {

        throw ex;
    }
}

但是,当这个请求被传递到控制器时,请求正文为空。

以前在 Core2.x 中你可以这样做

request.EnableRewind();

我的理解是现在替换为

httpContext.Request.EnableBuffering();

然而,即使有

httpContext.Request.EnableBuffering();

一旦请求正文被读取,请求正文仍然为空。

我怎样才能解决这个问题?

【问题讨论】:

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


    【解决方案1】:

    它是github上已知的issue

    临时解决方法是在调用 EnableBuffering 后立即拉出正文,然后将流倒回到 0 并且不释放它:

    public class RequestLoggingHandler : AuthorizationHandler<RequestLoggingRequirement>
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        public RequestLoggingHandler(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RequestLoggingRequirement requirement)
        {
            try
            {
                var httpContext = _httpContextAccessor.HttpContext;
                var request = httpContext.Request;
                request.EnableBuffering();
    
                httpContext.Items["requestId"] = SaveRequest(request);
                context.Succeed(requirement);
    
                return Task.CompletedTask;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private int SaveRequest(HttpRequest request)
        {
            try
            {
                // Allows using several time the stream in ASP.Net Core
                var buffer = new byte[Convert.ToInt32(request.ContentLength)];
                request.Body.ReadAsync(buffer, 0, buffer.Length);
                var requestContent = Encoding.UTF8.GetString(buffer);
                var requestId = _repository.SaveRawHandlerRequest($"{request.Scheme} {request.Host}{request.Path} {request.QueryString} {requestContent}");
    
                request.Body.Position = 0;//rewinding the stream to 0
                return requestId;
            }
            catch (Exception ex)
            {
    
                throw ex;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-23
      • 2021-03-13
      • 2016-04-20
      • 1970-01-01
      • 2020-10-25
      • 2019-11-30
      • 2017-08-18
      • 2015-10-02
      • 2020-08-03
      相关资源
      最近更新 更多