ASP.NET Core AsyncActionFilter用于记录ActionArguments和Result

时间:2017-09-14 06:09:23

标签: c# asp.net-core action-filter

我希望创建一个实现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>

那么,有没有办法在同一方法范围内同时访问ActionArgumentsResult

-S

2 个答案:

答案 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