getting the request body inside HttpContext from a Middleware in asp.net core 2.0

前端 未结 4 1810
礼貌的吻别
礼貌的吻别 2021-02-20 10:45

I am having a simple middleware which fetches the body of the request and store it in a string. It is reading fine the stream, but the issue is it wont call my controller which

相关标签:
4条回答
  • 2021-02-20 11:03

    Few things are crucial here:

    • enable buffering
    • last flag leaveOpen in StreamReader
    • reset request body stream position (SeekOrigin.Begin)
    public void UseMyMiddleware(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            context.Request.EnableBuffering();
    
            using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, false, 1024, true))
            {
                var body = await reader.ReadToEndAsync();
    
                context.Request.Body.Seek(0, SeekOrigin.Begin);
            }
    
            await next.Invoke();
        });
    }
    
    0 讨论(0)
  • 2021-02-20 11:04
    using (var mem = new MemoryStream())
                using (var reader = new StreamReader(mem))
                {
                    Request.Body.CopyTo(mem);
                    var body = reader.ReadToEnd();
    
    //and this you can reset the position of the stream.
    
                    mem.Seek(0, SeekOrigin.Begin);
                    body = reader.ReadToEnd();
                }
    

    Here you are can read how it works. https://gunnarpeipman.com/aspnet-core-request-body/

    0 讨论(0)
  • 2021-02-20 11:05

    You need to convert HttpContext.Request.Body from a forward only memory stream to a seekable stream, shown below.

    //  Enable seeking
    context.Request.EnableBuffering();
    //  Read the stream as text
    var bodyAsText = await new System.IO.StreamReader(context.Request.Body).ReadToEndAsync();
    //  Set the position of the stream to 0 to enable rereading
    context.Request.Body.Position = 0; 
    
    0 讨论(0)
  • 2021-02-20 11:10

    when it comes to capturing the body of an HTTP request and/or response, this is no trivial effort. In ASP .NET Core, the body is a stream – once you consume it (for logging, in this case), it’s gone, rendering the rest of the pipeline useless.

    Ref:http://www.palador.com/2017/05/24/logging-the-body-of-http-request-and-response-in-asp-net-core/

    public async Task Invoke(HttpContext httpContext)
        {
            var timer = Stopwatch.StartNew();
            string bodyAsText = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();
            var injectedRequestStream = new MemoryStream();
            var bytesToWrite = Encoding.UTF8.GetBytes(bodyAsText);
            injectedRequestStream.Write(bytesToWrite, 0, bytesToWrite.Length);
            injectedRequestStream.Seek(0, SeekOrigin.Begin);
            httpContext.Request.Body = injectedRequestStream;
            await _next(httpContext);
    
            timer.Stop();
        }
    
    0 讨论(0)
提交回复
热议问题