How to Read Request Body in an ASP.NET Core Webapi Controller

How can I read the Request Body in a .Net 5 Webapi project using an Action Filter

The model can be directly obtained in the action filter as shown below.

public void OnActionExecuting(ActionExecutingContext context)
{
var body = context.ActionArguments["someData"] as SomeData ;
}

Test result:
Sample Image

Reading request body in middleware for .Net 5

Usually Request.Body does not support rewinding, so it can only be read once. A temp workaround is to pull out the body right after the call to EnableBuffering and then rewinding the stream to 0 and not disposing it:

public class CreateSession
{
private readonly RequestDelegate _next;

public CreateSession(RequestDelegate next)
{
this._next = next;
}

public async Task Invoke(HttpContext httpContext)
{
var request = httpContext.Request;

request.EnableBuffering();
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
//get body string here...
var requestContent = Encoding.UTF8.GetString(buffer);

request.Body.Position = 0; //rewinding the stream to 0
await _next(httpContext);

}
}

Register the service:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
app.UseHttpsRedirection();

app.UseMiddleware<CreateSession>();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});

}

How can I read http request body in netcore 3 more than once?

It is a known issue on github.

A temp workaround is to pull out the body right after the call to EnableBuffering and then rewinding the stream to 0 and not disposing it:

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;
}
}
}

ASP.NET Core 3.1 get method body breaks the request

Change [HttpGet] for [HttpPost] and issue a POST request instead of a GET.

How to read request body multiple times in asp net core 2.2 middleware?

After some more struggling and use
"context.Request.EnableRewind()"
it's finally worked like this:

app.Use(async (context, next) =>
{
context.Request.EnableRewind();
var stream = context.Request.Body;

using (var reader = new StreamReader(stream))
{
var requestBodyAsString = await reader.ReadToEndAsync();

if (stream.CanSeek)
stream.Seek(0, SeekOrigin.Begin);

//Do some thing

await next.Invoke();

var responseStatusCode = context.Response.StatusCode;
//Do some other thing
}
});


Related Topics



Leave a reply



Submit