Як додати глобальні фільтри ASP.Net Web Api?


98

Я створив фільтр Web Api (використовуючи System.Web.Http.Filters.ActionFilterAttribute), але мені не вдається змусити його працювати всередині ASP.Net MVC 4. Я спробував додати його до RegisterGlobalFilters()методу, але це не спрацювало.

Отже, якщо використовується Web Api, розміщений в ASP.Net MVC, як один реєструвати фільтри?

Відповіді:


110

У моєму Global.asax працює такий код:

public static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection filters)
{
  filters.Add(new MyWebApiFilter());
}

protected void Application_Start()
{
  RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
}

6
Може хтось пояснить, що тут відбувається? Чому існує два набори глобальних фільтрів? Хіба це не робить «Глобального» оксимороном?
Люк Пуплетт

6
Один набір фільтрів призначений для MVC, а інший - для веб-API. Це дві окремі речі, і зазвичай ви не хочете, щоб фільтри застосовувались до іншого.
Шейн Кортріль

2
Мій фільтр WebApi викликається двічі. Хтось має цю проблему?
Андрій Калашников

87

зауважте, що ця відповідь відповідає дійсності до MVC 5 / Web API 2

Коротка відповідь: Фільтри MVC та Web API не є сумісними між собою, і якщо ви хочете зареєструвати їх у всьому світі, ви повинні використовувати відповідні класи конфігурації для кожного.

Довга відповідь: ASP.NET MVC та Web API призначені для роботи аналогічним чином, але вони насправді різні істоти.

Веб-API живе в System.Web.Httpпросторі імен, тоді як MVC живе в System.Web.Mvcпросторі імен. Двоє із задоволенням житимуть пліч-о-пліч, але одна не містить іншої, і незважаючи на подібність у моделі програмування, основні реалізації є різними. Так само, як контролери MVC та контролери Web API успадковують різні базові класи контролерів (MVC просто називають, Controllerа Web API називають ApiController) MVC фільтри та фільтри Web API успадковують від різнихFilterAttribute класів (обидва мають одне і те саме ім'я в цьому випадку, але це окремі класи, які живуть у відповідних просторах імен).

Глобальні фільтри Web API реєструються через HttpConfigurationдоступний вам об’єкт у Registerметоді WebApiConfig.cs, якщо ви використовуєте шаблон проекту з WebActivator:

public static void Register(HttpConfiguration config)
{
    //stuff before
    config.Filters.Add(new MyWebApiFilter());
    //stuff after
}

або іншим чином у global.asax.cs:

GlobalConfiguration.Configuration.Filters.Add(new MyWebApiFilter());

Глобальні фільтри Mvc реєструються за допомогою GlobalFilterCollectionоб’єкта, який доступний вам RegisterGlobalFiltersметодом FilterConfig.cs для проектів, які використовують WebActivator:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //stuff before
        filters.Add(new MyMvcFilter());
        //stuff after
    }
}

або у файл global.asax.cs шляхом GlobalFilters.Filtersколекції для тих, хто не має WebActivator:

GlobalFilters.Filters.Add(new MyMvcFilter());

Варто зазначити, що в обох випадках не потрібно успадковувати від відповідного FilterAttributeтипу. Веб-фільтрам API потрібно реалізувати лише інтерфейс System.Web.Http.IFilter, тоді як реєстрація MVC фільтрів перевіряє, чи відповідає ваш клас одному з декількох інтерфейсів фільтрів, визначених у System.Web.Mvcпросторі імен.


Додавання власних фільтрів Web Api у webapiconfig.cs працює для мене. Я не розумію, чому це не спрацювало, коли додано в global.asax.cs
Tatipaka

дякую @tatipaka. додавання до webapiconfig працював.
Гокулнат

12

Станом на MVC 4 RC, правильна назва класу - HttpFilterCollection :

public static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection filters)
{
    filters.Add(new MyWebApiFilter());
}

protected void Application_Start()
{
    RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
}

8

Замість використання глобальних фільтрів я вважаю за краще це робити:

[MyWebApiFilter]
public class CustomizedApiControllerBase : ApiController
{
   ...
}

А після цього успадковуйте всі контролери api від CustomizedApiControllerBase цього підходу є більш виразним порівняно з глобальними фільтрами у файлі global.ascx.


Я створив фільтр у спадок від System.Web.Http.Filters.ActionFilterAttribute і перейшов до його використання безпосередньо на потрібних мені методах. Це просто працює, тож чому мені не потрібно його реєструвати?
Joedotnot

@joedotnot Йдеться про "глобальні" фільтри, а не про конкретні. Якщо ви можете вказати, який метод ви хочете фільтрувати, ваш підхід у порядку, але коли ви хочете фільтрувати незалежно від дій контролера, вам потрібні глобальні фільтри.
Махмуд Моравей
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.