我希望创建一个实现IAsyncActionFilter
的过滤器,该过滤器将从当前请求的上下文ActionParameters
及其Result
中检索数据。我正在使用自定义属性MyLogAttribute
来指导日志记录,例如选择加入以记录和指示包含关键信息的字段。
public class AsyncMyLogFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (actionDescriptor != null)
{
var attribute = actionDescriptor.MethodInfo.GetCustomAttribute<MyLogAttribute>();
if (attribute != null)
{
await next();
// This is where the magic is supposed to happen:
LoggerHelper.Log(context.ActionArguments, context.Result);
}
return;
}
await next();
}
}
过滤器提供next()
委托的方式让我相信,在此之后行动将完成,结果对象可以作为ObjectResult
进行检查。但是,虽然过滤器能够毫无问题地抓取ActionArguments
,但遗憾的是Result
属性为空,这根本没有用。
显而易见的替代方法IActionFilter
允许我检查Result
阶段上的OnActionExecuted
对象,但此时ActionArguments
字典不可用。< / p>
那么,有没有办法在同一方法范围内同时访问ActionArguments
和Result
?
-S
答案 0 :(得分:1)
next()
的结果将是结果背景。
此代码示例来自Filters documentation
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
namespace FiltersSample.Filters
{
public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next)
{
// do something before the action executes
var resultContext = await next();
// do something after the action executes; resultContext.Result will be set
}
}
}
答案 1 :(得分:0)
虽然原始表单中的问题尚未解决,但我能够使用IActionFilter
创建解决方法:
public class ActivityLogFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (actionDescriptor != null)
{
var attribute = actionDescriptor.MethodInfo.GetCustomAttribute<MyLogAttribute>();
if (attribute != null)
{
context.HttpContext.Items["MyLogData"] = GetRelevantLogData(context.ActionArguments); // Apply some custom logic to select relevant log data
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (actionDescriptor != null)
{
var attribute = actionDescriptor.MethodInfo.GetCustomAttribute<MyLogAttribute>();
if (attribute != null)
{
var actionParametersData = (MyActionParametersLogData)context.HttpContext.Items["MyLogData"]
LoggerHelper.Log(actionParametersData, context.Result);
}
}
}
}
}
不完全是火箭科学;它看起来有点脆弱(“如果我的HttpContext项目丢失了怎么办??”),但它似乎可以完成这项工作。
-S