阅读ActionFilterAttribute中的Asp.Net核心响应正文
我正在使用Asp.NETCore作为RESTAPI服务。 我需要访问ActionFilter中的请求和响应。实际上,我在OnActionExcecuted中找到了请求,但我无法读取响应结果 我尝试按如下方式返回值:阅读ActionFilterAttribute中的Asp.Net核心响应正文,asp.net,asp.net-mvc,asp.net-core,.net-core,Asp.net,Asp.net Mvc,Asp.net Core,.net Core,我正在使用Asp.NETCore作为RESTAPI服务。 我需要访问ActionFilter中的请求和响应。实际上,我在OnActionExcecuted中找到了请求,但我无法读取响应结果 我尝试按如下方式返回值: [HttpGet] [ProducesResponseType(typeof(ResponseType), (int)HttpStatusCode.OK)] [Route("[action]")] public async Task<IActionResult> Get(
[HttpGet]
[ProducesResponseType(typeof(ResponseType), (int)HttpStatusCode.OK)]
[Route("[action]")]
public async Task<IActionResult> Get(CancellationToken cancellationToken)
{
var model = await _responseServices.Get(cancellationToken);
return Ok(model);
}
_request = context.HttpContext.Request.ReadAsString().Result;
_response = context.HttpContext.Response.ReadAsString().Result; //?
public static async Task<string> ReadAsString(this HttpResponse response)
{
var initialBody = response.Body;
var buffer = new byte[Convert.ToInt32(response.ContentLength)];
await response.Body.ReadAsync(buffer, 0, buffer.Length);
var body = Encoding.UTF8.GetString(buffer);
response.Body = initialBody;
return body;
}
我试图在ReadAsString中作为扩展方法获取响应,如下所示:
[HttpGet]
[ProducesResponseType(typeof(ResponseType), (int)HttpStatusCode.OK)]
[Route("[action]")]
public async Task<IActionResult> Get(CancellationToken cancellationToken)
{
var model = await _responseServices.Get(cancellationToken);
return Ok(model);
}
_request = context.HttpContext.Request.ReadAsString().Result;
_response = context.HttpContext.Response.ReadAsString().Result; //?
public static async Task<string> ReadAsString(this HttpResponse response)
{
var initialBody = response.Body;
var buffer = new byte[Convert.ToInt32(response.ContentLength)];
await response.Body.ReadAsync(buffer, 0, buffer.Length);
var body = Encoding.UTF8.GetString(buffer);
response.Body = initialBody;
return body;
}
公共静态异步任务ReadAsString(此HttpResponse响应)
{
var initialBody=response.Body;
var buffer=新字节[Convert.ToInt32(response.ContentLength)];
wait response.Body.ReadAsync(buffer,0,buffer.Length);
var body=Encoding.UTF8.GetString(缓冲区);
response.Body=initialBody;
返回体;
}
但是,没有结果
如何在OnActionExcecuted中获得响应
感谢大家花时间尝试并帮助解释如果您正在记录json结果/查看结果,您不需要阅读整个响应流。只需序列化
上下文。结果
:
public class MyFilterAttribute : ActionFilterAttribute
{
private ILogger<MyFilterAttribute> logger;
public MyFilterAttribute(ILogger<MyFilterAttribute> logger){
this.logger = logger;
}
public override void OnActionExecuted(ActionExecutedContext context)
{
var result = context.Result;
if (result is JsonResult json)
{
var x = json.Value;
var status = json.StatusCode;
this.logger.LogInformation(JsonConvert.SerializeObject(x));
}
if(result is ViewResult view){
// I think it's better to log ViewData instead of the finally rendered template string
var status = view.StatusCode;
var x = view.ViewData;
var name = view.ViewName;
this.logger.LogInformation(JsonConvert.SerializeObject(x));
}
else{
this.logger.LogInformation("...");
}
}
公共类MyFilterAttribute:ActionFilterAttribute
{
私人ILogger记录器;
公共MyFilterAttribute(ILogger记录器){
this.logger=记录器;
}
公共覆盖无效OnActionExecuted(ActionExecutedContext上下文)
{
var result=context.result;
if(结果为JsonResult json)
{
var x=json.Value;
var status=json.StatusCode;
this.logger.LogInformation(JsonConvert.SerializeObject(x));
}
如果(结果是视图结果视图){
//我认为最好记录ViewData,而不是最终呈现的模板字符串
var status=view.StatusCode;
var x=view.ViewData;
var name=view.ViewName;
this.logger.LogInformation(JsonConvert.SerializeObject(x));
}
否则{
this.logger.LogInformation(“…”);
}
}
我知道已经有了答案,但我还想补充一点,问题是MVC管道在运行ActionFilter
时没有填充响应.Body
,因此您无法访问它。响应.Body
由MVC中间件填充
如果要阅读Response.Body
,则需要创建自己的自定义中间件,以便在填充响应对象时拦截调用。有许多网站可以向您展示如何执行此操作。例如
正如在另一个答案中所讨论的,如果您想在ActionFilter
中执行此操作,您可以使用上下文.Result
来访问信息。您也可以执行以下操作
string response = "Hello";
if (result is ObjectResult objectResult)
{
var status = objectResult.StatusCode;
var value = objectResult.Value;
var stringResult = objectResult.ToString();
responce = (JsonConvert.SerializeObject(value));
}
我在一个.net核心应用程序中使用了这个
希望对您有所帮助。对于在ASP.NET核心过滤器管道中记录整个请求和响应,您可以使用
在Startup.cs中添加
app.UseMiddleware<ResponseRewindMiddleware>();
services.AddScoped<LogRequestResponseAttribute>();
你可以从感谢中得到想法,我尝试了很多方法,但所有主题都没有得到回应。你为什么要阅读回应?虽然阅读回应是可能的,但如果你告诉我们你的意图,也许有更好的方法来实现你的目标。这可能有助于你我需要知道哪些数据提供给client并将所有结果记录为JSON@itminus。这个答案比我见过的其他常见解决方案要高效得多(不管怎样,在代码方面),这些解决方案似乎普遍建议替换和跟踪响应。Body
的内存流!谢谢!