如何将服务注入自定义过滤器属性MVC

问题描述 投票:2回答:2

我具有如下所示的自定义日志记录属性:

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-mvc action-filter actionfilterattribute asp.net-mvc-custom-filter
2个回答
0
投票

您必须将属性与actionfilter分开。保持属性简单明了:

[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.
    }
}

不要忘记在启动时注册您的actionfilter:

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

甚至更好:您现在可以使用IAsyncActionFilter


0
投票

根据我的第一个分析,您的代码不应该编译,您尝试使用的代码在ASP.Net中称为过滤器。

过滤器定义:

ASP.NET MVC筛选器是一个自定义类,您可以在其中编写要在执行操作方法之前或之后执行的自定义逻辑。可以以声明或编程方式将过滤器应用于操作方法或控制器。声明方法是通过将过滤器属性应用于动作方法或控制器类,编程方法是通过实现相应的接口。

documention source

1-第一步:(创建您的过滤器)

public class TestFilter : ActionFilterAttribute
{
    private readonly ILoggerService loggerService;

    public TestFilter():this(new LoggerService())
    {

    }

    public TestFilter(ILoggerService loggerService)
    {
        this.loggerService = loggerService;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
    }
}

2-第二步:(注册您的过滤器)

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new TestFilter());
}

3-第三步:(将过滤器集成到控制器或操作中)

[TestFilter]
public class CustomerController : Controller
{
    .....
}

第一步,我手动实例化了我的记录器,但是在您的情况下,您应该通过界面自动解决记录器,您可以做的是用您自己的代码替换这段代码。

© www.soinside.com 2019 - 2024. All rights reserved.