How to read request body in OnActionExecuting(ActionExecutingContext context) in IActionFilter Asp.net core

10,030

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 ;
Share:
10,030

Related videos on Youtube

user6885473
Author by

user6885473

Updated on July 24, 2022

Comments

  • user6885473
    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 string

    I 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
    Royi Namir almost 3 years
    This is the correct answer. @downvoter. care to comment ?
  • suchoss
    suchoss almost 3 years
    I 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/…