I am trying to read the body in a middleware for authentication purposes, but when the request gets to the api controller the object is empty as the body has already been read. Is there anyway around this. I am reading the body like this in my middleware.
var buffer = new byte[ Convert.ToInt32( context.Request.ContentLength ) ]; await context.Request.Body.ReadAsync( buffer, 0, buffer.Length ); var body = Encoding.UTF8.GetString( buffer );
If you're using application/x-www-form-urlencoded
or multipart/form-data
, you can safely call context.Request.ReadFormAsync()
multiple times as it returns a cached instance on subsequent calls.
If you're using a different content type, you'll have to manually buffer the request and replace the request body by a rewindable stream like MemoryStream
. Here's how you could do using an inline middleware (you need to register it soon in your pipeline):
app.Use(next => async context => { // Keep the original stream in a separate // variable to restore it later if necessary. var stream = context.Request.Body; // Optimization: don't buffer the request if // there was no stream or if it is rewindable. if (stream == Stream.Null || stream.CanSeek) { await next(context); return; } try { using (var buffer = new MemoryStream()) { // Copy the request stream to the memory stream. await stream.CopyToAsync(buffer); // Rewind the memory stream. buffer.Position = 0L; // Replace the request stream by the memory stream. context.Request.Body = buffer; // Invoke the rest of the pipeline. await next(context); } } finally { // Restore the original stream. context.Request.Body = stream; } });
You can also use the BufferingHelper.EnableRewind()
extension, which is part of the Microsoft.AspNet.Http
package: it's based on a similar approach but relies on a special stream that starts buffering data in memory and spools everything to a temp file on disk when the threshold is reached:
app.Use(next => context => { context.Request.EnableRewind(); return next(context); });
FYI: a buffering middleware will probably be added to vNext in the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With