Фильтр, подобный BeginRequest, в MVC 3?

В моем приложении есть некоторый код, который мне нужно выполнять при каждом запросе, до того, как будет выполнено что-либо еще (даже до аутентификации). До сих пор я использовал событие Application_BeginRequest в своем Global.asax, и это работало нормально. Но этот код должен попасть в базу данных, а выполнение этого из Global.asax по какой-то причине кажется неправильным. Кроме того, nuget Ninject.MVC3, который я использую, не будет внедрять зависимости в мой HttpApplication ctor.

Поэтому я решил переместить этот код в собственный глобальный фильтр действий. Проблема, с которой я столкнулся сейчас, заключается в том, что независимо от того, какой Order или FilterScope я задаю этому фильтру, я не могу заставить его выполняться первым; мой фильтр авторизации всегда превосходит его. MSDN, кажется, подтверждает это:

Порядок фильтрации

Фильтры работают в следующем порядке:

  1. Фильтры авторизации
  2. Фильтры действий
  3. Фильтры ответов
  4. Фильтры исключений

Например, фильтры авторизации запускаются первыми, а фильтры исключений — последними. В каждом типе фильтра значение Order определяет порядок выполнения. В каждом типе и порядке фильтра значение перечисления Scope определяет порядок фильтров.

Я знаю, что могу использовать HttpModule, но это не очень похоже на MVCish, поэтому я пытаюсь исчерпать все возможности, прежде чем идти по этому пути, что приводит к моему вопросу:

Есть ли эквивалент BeginRequest для глобальных фильтров действий?


person Daniel Liuzzi    schedule 02.02.2011    source источник


Ответы (1)


Вы можете сделать это в разделе Инициализировать. метод базового контроллера.

Другая возможность — зарегистрировать ссылку глобальный фильтр:

public class MyGlobalFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // that's gonna be hit
    }
}

и в событии RegisterGlobalFilters вашего Global.asax:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new MyGlobalFilter());
}
person Darin Dimitrov    schedule 02.02.2011
comment
Я использую DI, поэтому новый оператор отсутствует :( Инициализация в базовом контроллере действительно работала. Однако вынужденное наследование от базового типа кажется немного ограничивающим; вся причина, по которой я пытался сделать это с помощью фильтров (или — хотя и нежелательно — HTTP-модули) из-за их модульности. - person Daniel Liuzzi; 03.02.2011
comment
@ Даниэль, что мешает тебе сделать filters.Add(DIContainer.Get<MyGlobalFilter>());, если ты не хочешь использовать оператор new? - person Darin Dimitrov; 03.02.2011
comment
ничто не мешает мне это сделать. Но я бы предпочел не вызывать контейнер напрямую, так как это будет расположение службы, а не инверсия управления. Кроме того, я не чувствую себя комфортно, делая свой код настолько тесно связанным с Ninject, поэтому я пытаюсь свести использование kernel.Get‹T›() к минимуму. - person Daniel Liuzzi; 03.02.2011
comment
@Daniel, тогда вы, вероятно, найдете следующий пост в блоге полезно. - person Darin Dimitrov; 03.02.2011