首页 > 解决方案 > 如何将服务注入自定义过滤器属性 MVC

问题描述

我有一个自定义日志记录属性,如下所示:

public class LoggerAttribute: ActionFilterAttribute
    {

        private readonly IHttpLogService _httpLogService;
        private readonly ILogService _logService;
        public LoggerAttribute(IHttpLogService httpLogService, ILogService logService)
        {
            _httpLogService = httpLogService;
            _logService = logService;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            LogDetails(filterContext);
        }

        private void LogDetails(ActionExecutingContext filterContext)
        {
            try
            {
                HttpLogService httpService = new HttpLogService();
                var httplogger = new LogMetaData()
                {
                    RequestParams = filterContext,
                    ResponseParams  = filterContext
                };
                _httpLogService.Emit("source", "", "Name", httplogger);
            }
            catch (Exception ex)
            {
                _logService.Emit(Core.Enums.LogLevel.Error, "token", "Error encountered while trying to execute the request.", ex);
                throw new Exception("An error occurred. Please try again later.");
            }
        }
    }

以下是我需要执行上述过滤器的控制器操作方法的代码,但下面的代码不起作用,因为我不确定如何通过属性传递服务:

[LoggerAttribute]
public int testMethod(RequestObject obj)
{
-----
}

IHttpLogService 和 ILogService 是我需要注入到我的自定义过滤器属性中的一个。但我不太确定如何做到这一点。有人可以帮我解决这个问题吗?

标签: c#asp.net-mvcaction-filteractionfilterattributeasp.net-mvc-custom-filter

解决方案


您必须将属性与操作过滤器分开。保持属性简单明了:

[AttributeUsage(AttributeTargets.Method)]
public class LoggerAttribute : Attribute
{
}

让您的 actionfilter 发挥作用:

public class LoggerActionFilter : IActionFilter
{
    // Can inject stuff in the constructor

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // You may need some more null checking here...
        var attribute = ((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.GetCustomAttributes(true).OfType<LoggerAttribute>().FirstOrDefault();
        if (attribute is null)
        {
            return;
        }

        // Work your logger magic here.
    }
}

不要忘记在启动时注册您的操作过滤器:

services.AddControllersWithViews(options =>
{
    options.Filters.Add(typeof(LoggerActionFilter));
});

更好的是:您现在可以使用IAsyncActionFilter


推荐阅读