我编写了在服务器方法调用后运行的过滤器,并将其内容打印到控制台。该代码是用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);
}
}
结果-异常:
流不可读。
进一步的研究使我发现流(context.HttpContext.Response
)具有以下值:
这可以解释为什么它无法读取身体...
如何解决?
答案 0 :(得分:1)
不确定为什么要这样做。 context.Result
是IActionResult
的实例,您可以根据需要进行操作。如果您确实想阅读Response.Body
,则可以做些骇人听闻的事情。
由于默认的Response.Body
是不可读的Stream
,为了使主体可读,我们需要劫持响应,即将Body
替换为我们自己的Stream
的实例:
Response.Body
流。 StreamReader
读取流,做一些工作,然后设置Response.Body=your new stream
。用普通的内存流劫持Response.Body
是安全的,因为Body
的类型是普通的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);
}
}
出于测试目的,我创建了一个操作方法:
[MyCustomFilter]
public IActionResult Index()
{
return Ok("it wooooooooorks");
}
答案 1 :(得分:1)
使用 Actionfilter 而不是中间件:
var resultnext = await next();
var objectResult = resultnext.Result as ObjectResult;
var resultValue = objectResult.Value;
答案 2 :(得分:0)
这完全取决于您要实现的目标。 如果您想获取响应值或仅查看结果,可以使用
context.Result or context.Result.Value
如果您要修改响应或仅记录整个响应,则应使用中间件。
这是一个很好的例子https://exceptionnotfound.net/using-middleware-to-log-requests-and-responses-in-asp-net-core/
希望有帮助