Глобальные фильтры и переопределение фильтров

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

Глобальные фильтры

Мы посмотрели на различные виды фильтров. Как вы видели, мы можем применить фильтры как к отдельным действиям, так и ко всему контроллеру - то есть ко всем его действиям. Однако если мы хотим применить фильтр ко всем контроллерам, а контроллеров у нас много? В данном случае в mvc реализована функциональность глобальных фильтров. Эти фильтры применяются ко всем действиям всех контроллеров.

Откроем файл FilterConfig.cs, который находится в папке App_Start. В этом файле определен класс FilterConfig, который в методе RegistreGlobalFilters осуществляет регистрацию глобальных фильтров в коллекцию filters. Эта коллекция представляет собой объект GlobalFilterCollection, который передается в качестве параметра при вызове метода в файле Global.asax.

Итак, мы можем зарегистрировать глобальные фильтры так:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
			
        filters.Add(new MyExceptionAttribute());
        filters.Add(new MyResultAttribute());
    }
}

Переопределение фильтров

Одним из нововведений MVC 5 стала такая функциональность как переопределение фильтров. Чтобы понять ее суть, рассмотрим следующую ситуацию. Например, у нас есть контроллер с ограничением доступа:

[Authorize(Users = "eugene")]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [Authorize(Users = "sergey")]
    public string Test()
    {
        return "Test";
    }
}

Атрибут авторизации на уровне контроллера [Authorize(Users = "eugene")] ограничивает доступ к методам контроллера: в данном случае они доступны только пользователю с логином eugene. И очевидно, что второй атрибут авторизации для метода Test работать не будет.

Однако такая возможность была бы очень плезна, особенно при использовании глобальных фильтров, когда нам надо открыть или переопределить доступ. Проблема касается не только фильтров авторизации, но и любых других.

И чтобы решить данную проблему в MVC 5 была введена такая функциональность, как переопределение фильтров. Она подразумевает реализацию интерфейса IOverrideFilter:

namespace System.Web.Mvc.Filters
{
    public interface IOverrideFilter : IFilter
    {
        Type FiltersToOverride{get;};
    }
}

Единственное свойство интефрейса позволяет указать тип фильтров, которые надо переопределить. Итак, создадим новый класс, реализующий данный интерфейс:

public class OverrideFilterAttribute : FilterAttribute, IOverrideFilter
{
    public Type FiltersToOverride
    {
        get { return typeof(IAuthorizationFilter); }
    }
}

Так как нам надо переопределить поведение фильтров авторизации, то в качестве типа указывается IAuthorizationFilter. И теперь мы можем переписать контроллер следующим образом:

[Authorize(Users = "eugene")]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

	[OverrideFilter]
    [Authorize(Users = "sergey")]
    public string Test()
    {
        return "Test";
    }
}

Таким образом, фильтр авторизации [Authorize(Users = "eugene")] будет применяться ко всем действиям контроллера, кроме метода Test.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850