Reading the Response.Body stream in Filter

前端 未结 2 1374
不思量自难忘°
不思量自难忘° 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");
    }
    

提交回复
热议问题