7

Mam prostą aplikację ASP.Net MVC 3, która ma trochę kontrolera i kilka dobrych akcji.ASP.Net MVC 3: Inverse Authorize Attribute

Teraz, ponieważ jest to aplikacja oparta na użytkownikach, większość działań kontrolera wymaga uwierzytelnienia użytkownika. MVC radzi sobie z tym dobrze dzięki wbudowanemu atrybutowi Authorize, który można wykorzystać do dekorowania kontrolerów i/lub działań indywidualnie.

Wspaniałą rzeczą jest to, można zastosować atrybut tylko sterownik i wszystkie działania dla tej danej kontroler będzie miał on stosowany zbyt - Dużo pisania zbawiony;) ​​

Ale mam jeden kontroler z, powiedzmy, 10 działań. Ale chcę, aby jedna z akcji nie zastosowała atrybutu Authorize.

Tak, mógłbym zastosować atrybut do pozostałych 9 i usunąć go ze sterownika, który zrobi dokładnie to, czego potrzebuję. Ale czy istnieje sposób, aby utrzymać to zastosowanie do kontrolera i po prostu wybrać wyłączenie jednego z działań?

Skutecznie, chciałby coś takiego ...

[!Authorize] lub [NotAuthorize]

wiem mogę utworzyć jeden niestandardowy, który będzie wykonać zadanie, ale to, co chcę wiedzieć, czy jest wbudowany - w jaki sposób to zrobić? lub czy muszę zastosować atrybut do wszystkich 9 innych działań?

Odpowiedz

2

Phil Haack napisał blogu niedawno do czynienia z dokładnie tym scenariuszu:

Conditional Filters in ASP.NET MVC 3

Jego rozwiązanie obejmuje pisanie zwyczaj „warunkowy dostawca filtr”, który pozwala wyznaczyć stan filtra do atrybutów działania metoda.

Szczegóły i uzasadnienie znajdują się w jego poście, ale kod jest stosunkowo prosty. Najpierw utwórz dostawcę filtra:

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); 
    } 
} 

a następnie zastosowanie go:

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); 
10

pamiętać, że nowy atrybut został dodany w ASP.NET MVC 4,0 że robi dokładnie to:
[AllowAnonymous]