Last post Nov 19, 2019 05:08 PM by mKamiAsim
Nov 17, 2019 10:30 AM|mKamiAsim|LINK
I have upgraded my project from .net core 2.2 to .net core 3.0.
I had created a middleware which log request and response of each API call. As in .net core 2.2 I am using stream from HttpRequest and HttpResponse to get string data, but in .Net core 3.0 we have Pipelines (BodyReader/BodyWriter). I want to migrate my code.
Currently I am facing issue in Logging request. I get the request body information from BodyReader, but It seems I am missing something, which does not pass request body to next middleware. So I am receiving Json error.
For I am attaching the sample project file. I partially implemented the request logging, but its not working (as Json request is not transfering to next middleware). Here is error I am receiving in response
"The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0."
For response logging, can you please provide guideline, Can I use the HttpResponseBody stream, or can follow other better options.
Project file is uploaded here
Nov 18, 2019 12:05 PM|Sherry Chen|LINK
Hi mKamiAsim ,
From the System.IO.Pipelines: High performance IO in .NET and Experimenting with
System.IO.Pipelines for high performance audio,
One thing to be aware of is that after you call AdvanceTo you will not get anything back from the pipe reader until there has been another write (even if you didn't "examine" all the way to the end of the buffer).
HttpRequest.BodyReader is a
PipeReader. PipeReader has two core APIs ReadAsync and AdvanceTo. ReadAsync gets the data in the Pipe, AdvanceTo tells the PipeReader that these buffers are no longer required by the reader so they can be discarded (for example returned to the underlying
You could try to read the request body using stream ,and use EnableBuffering()
to enable read the request more than once like the below example:
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
var bodyStr = "";
var req = context.Request;
using (StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
bodyStr = await reader.ReadToEndAsync();
req.Body.Position = 0;
Best Regards ,
Nov 18, 2019 06:38 PM|mKamiAsim|LINK
Thanks sheryy Chen for your response. I didn't know much about pipeline, but I found pipelines are much better then stream. Thank for providing me article reference, I will explore more pipelines.
The suggestion you shared with me, I already did this in .NET core 2.2, but When I enabled EnableBuffering() (In previous framework I used Rewind()), I am receiving the error Cannot access a disposed object.
At which level the object is disposed, I received this error at line await next(Context).
Nov 19, 2019 09:00 AM|Sherry Chen|LINK
The code that I provided worked well in your shared project . Could you show the code of your modified part?
Nov 19, 2019 05:08 PM|mKamiAsim|LINK
Hi Sherry Chen,
Yes your code is working fine. Actually I created stream and never keep opened. Later I fixed it. Thanks for your kind support.