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 MyCustomFilter : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext context)
{
// ERROR on the next line!
using (StreamReader sr = new StreamReader(context.HttpContext.Response.Body))
{
Console.WriteLine(sr.ReadToEnd());
}
base.OnResultExecuted(context);
}
}
The result - exception:
Stream was not readable.
Further investigation leads me to the point that the stream (context.HttpContext.Response
) has those values:
That can explain why it cant read the body...
How to solve?
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
:
Response.Body
stream . 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");
}
Use Actionfilter instead of middleware:
var resultnext = await next();
var objectResult = resultnext.Result as ObjectResult;
var resultValue = objectResult.Value;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With