Как внедрить службу в атрибут пользовательского фильтра MVC - PullRequest
2 голосов
/ 09 апреля 2020

У меня есть пользовательский атрибут ведения журнала, как показано ниже:

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 - это то, что мне нужно вставить в мой атрибут настраиваемого фильтра. Но я не совсем уверен, как я могу это сделать. Может кто-нибудь помочь мне с этим?

Ответы [ 2 ]

0 голосов
/ 10 апреля 2020

Согласно моему первому анализу, ваш код не должен компилироваться, то, что вы пытаетесь использовать, называется фильтром в ASP. Net.

Определение фильтра:

ASP. NET MVC Фильтр - это пользовательский класс, в котором вы можете написать собственные логики c для выполнения до или после выполнения метода действия. Фильтры могут применяться к методу действия или контроллеру декларативным или программным способом c. Декларативные средства путем применения атрибута фильтра к методу действия или классу контроллера, а программные средства c означают реализацию соответствующего интерфейса.

источник документации

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

На первом шаге я вручную создал мой регистратор, но в вашем случае вы должны разрешить регистратор автоматически через ваш интерфейс, что вы можете сделать, это заменить этот фрагмент кода вашим собственным кодом.

0 голосов
/ 09 апреля 2020

Вам придется отделить атрибут от фильтра действий. Сохраняйте атрибут простым и понятным:

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

И пусть ваш actionfilter сделает волхвы c:

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 сейчас!

...