Reading the Response.Body stream in Filter

前端 未结 2 1371
不思量自难忘°
不思量自难忘° 2021-01-20 01:33

I writing my filter that running after a sever method call and print its content to Console. The code is written in ASP.NET core v2.1:

public class MyCustomF         


        
相关标签:
2条回答
  • 2021-01-20 01:51

    Not sure why you need to do this . context.Result is an instance of IActionResult , you can manipulate it as you like . If you do want to read the Response.Body , there's something hacky can be done.

    Since the default Response.Body is not a readable Stream , in order to make the body readable , we need to hijack the response , namely replace the Body with our own instance of Stream :

    1. We can create a brand new memory stream dynamically before action is executing , and hijack the default Response.Body stream .
    2. When action executed , read the stream using a StreamReader, do some work, and set the Response.Body=your new stream .

    It's safe to hijack the Response.Body with a plain memory stream because the type of Body is plain Stream.

    public class MyCustomFilter : ActionFilterAttribute
    {
        private MemoryStream responseBody ;
    
        public override void OnActionExecuting(ActionExecutingContext context){
            this.responseBody=new MemoryStream();
            // hijack the real stream with our own memory stream 
            context.HttpContext.Response.Body = responseBody;
        }
    
        public override void OnResultExecuted(ResultExecutedContext context)
        {
    
            responseBody.Seek(0, SeekOrigin.Begin);
    
            // read our own memory stream 
            using (StreamReader sr = new StreamReader(responseBody))
            {
                var actionResult= sr.ReadToEnd();
                Console.WriteLine(actionResult);
                // create new stream and assign it to body 
                // context.HttpContext.Response.Body = ;
            }
    
            // no ERROR on the next line!
    
            base.OnResultExecuted(context);
        }
    }
    

    For a testing purpose , I create an action method :

    [MyCustomFilter]
    public IActionResult Index()
    {
        return Ok("it wooooooooorks");
    }
    

    0 讨论(0)
  • 2021-01-20 02:14

    It all depends on what do you want to achieve. If you want to get the response values or just to see the result you can use

    context.Result or context.Result.Value
    

    If you want to modify the response or just to log the entire response you should use a middleware.

    here is a good example https://exceptionnotfound.net/using-middleware-to-log-requests-and-responses-in-asp-net-core/

    hope it helps

    0 讨论(0)
提交回复
热议问题