How to read request body in OnActionExecuting(ActionExecutingContext context) in IActionFilter Asp.net core
Solution 1
Here you need to go for the middleware approach.Read the documentation Middleware
if you want to read stream you must have to request.EnableRewind().because of Request. body
is a read and forward only stream that doesn't support reading the stream a second time.
request.EnableRewind();
after reading apply your logic and after that the request you need to add original stream back on the Response. Body
public void OnActionExecuting(ActionExecutingContext context)
{
var request = context.HttpContext.Request;
try
{
request.EnableRewind();
using (StreamReader reader = new StreamReader(request.Body))
{
return reader.ReadToEnd();
}
}
finally
{
request.Body = request;
}
context.Request.Body.Position = 0
return string.Empty;
}
You should have to set stream position zero(0)
request.Body.Position = 0 .
Otherwise, you will get empty body exception.
Solution 2
You can use :
var body = context.ActionArguments["info"] as InfoReq ;
Related videos on Youtube
user6885473
Updated on July 24, 2022Comments
-
user6885473 almost 2 years
I am sending AES encrypted request body to controller following is a sample:
(using crypto-js) {body: "U2FsdGVk186Jj7LySqT966qTdpQZwiR+wR0GjYqBzR4ouFAqP8Dz8UPPTv"}
I have created action filter, so whenever the request is posted I can decrypt the request in action filter than pass the decrypted request to the desired controller.
request after decryption :
{Name: "admin123" }
so how to get encrypted request body in action filter? and how to pass decrypted request body to the controller
I have tried WEB API in ASP.NET core
StreamReader
but it is returning an empty stringI want to pass decrypted request body to the controller
filter
public void OnActionExecuting(ActionExecutingContext context) { var req = context.HttpContext.Request; using (StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true)) { bodyStr = reader.ReadToEnd(); } req.Body.Position = 0; }
controller
[HttpPost("[action]")] public async Task<string> MyControllerName(InfoReq info) { }
class
public class InfoReq { public string Name{ get; set; } }
-
Royi Namir almost 3 yearsThis is the correct answer. @downvoter. care to comment ?
-
suchoss almost 3 yearsI agree that this works. I was wondering how is it possible. But then I looked at the lifecycle of action filters and there I saw it. ActionFilter goes after Model binding therefore Body stream has been already read and data are already parsed. Source: docs.microsoft.com/en-us/aspnet/core/mvc/controllers/…