ASP.Net MVC 3: обратный атрибут авторизации

У меня есть простое приложение ASP.Net MVC 3 с контроллером и несколькими хорошими действиями.

Теперь, поскольку это пользовательское приложение, большинство действий контроллера требуют аутентификации пользователя. MVC хорошо справляется с этим с помощью встроенного атрибута Authorize, который вы можете использовать для индивидуального оформления контроллеров и / или действий.

Самое замечательное, что вы можете применить атрибут только к контроллеру, и все действия для этого контроллера также будут применены - сохраняется много набора текста;)

Но у меня есть один контроллер, скажем, с 10 действиями. Но я хочу, чтобы к одному из действий не применялся атрибут авторизации.

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

Фактически, хотелось бы чего-то вроде ...

[!Authorize] or [NotAuthorize]

Я знаю, что могу создать собственный, который будет выполнять эту работу, но я хочу знать, есть ли встроенный способ сделать это? или мне нужно применить атрибут ко всем 9 другим действиям?


person musefan    schedule 03.11.2011    source источник


Ответы (2)


Фил Хаак недавно написал в блоге сообщение, посвященное именно этому сценарию:

Условные фильтры в ASP.NET MVC 3

Его решение включает в себя создание настраиваемого «поставщика условных фильтров», который позволяет назначать условие фильтрации атрибутам метода действия.

Подробности и рассуждения в его посте, но код относительно прост. Сначала создайте поставщик фильтра:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

public class ConditionalFilterProvider : IFilterProvider {
  private readonly 
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> _conditions;

  public ConditionalFilterProvider(
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions)
  {

      _conditions = conditions;
  }

  public IEnumerable<Filter> GetFilters(
      ControllerContext controllerContext, 
      ActionDescriptor actionDescriptor) {
    return from condition in _conditions
           select condition(controllerContext, actionDescriptor) into filter
           where filter != null
           select new Filter(filter, FilterScope.Global, null);
  }
}

А затем примените его:

IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions = 
    new Func<ControllerContext, ActionDescriptor, object>[] { 

    (c, a) => c.Controller.GetType() != typeof(HomeController) ? 
      new MyFilter() : null,
    (c, a) => a.ActionName.StartsWith("About") ? new SomeFilter() : null
};

var provider = new ConditionalFilterProvider(conditions);
FilterProviders.Providers.Add(provider);
person Eric King    schedule 03.11.2011

Обратите внимание, что в ASP.NET MVC 4.0 был добавлен новый атрибут, который выполняет именно это:
[AllowAnonymous]

person Xavier Poinas    schedule 12.07.2012