7

Tengo una aplicación simple ASP.Net MVC 3 que tiene un controlador y unas pocas acciones.ASP.Net MVC 3: Atributo Autorizar Inverso

Ahora, como se trata de una aplicación basada en el usuario, la mayoría de las acciones del controlador requieren que el usuario se autentique. MVC maneja esto bien con el atributo Authorize incorporado que puede usar para decorar controladores y/o acciones individualmente.

Lo bueno es que se puede aplicar el atributo de sólo el controlador y todas las acciones para que el controlador dado habrá que aplicarse también - un montón de mecanografía guardados;)

Pero tengo un controlador con, digamos, 10 acciones. Pero quiero que una de las acciones no tenga el atributo Autorizar aplicado.

Sí, podría aplicar el atributo a los otros 9 y eliminarlo del controlador, que hará exactamente lo que necesito. Pero, ¿hay alguna manera de mantenerlo aplicado al controlador y simplemente elegir excluir una de las acciones?

Efectivamente, querría algo así como ...

[!Authorize] o [NotAuthorize]

Sé que podría crear uno personalizado que va a hacer el trabajo, pero lo que quiero saber es si hay una construida -en la forma de hacer esto? o ¿tengo que aplicar el atributo a las otras 9 acciones?

Respuesta

2

Phil Haack escribió una publicación reciente que trata con este escenario exacto:

Conditional Filters in ASP.NET MVC 3

Su solución incluye escribir una costumbre "proveedor de filtro condicional" que permite a designar una condición de filtro a los atributos de una acción método.

Los detalles y el razonamiento están en su publicación, pero el código es relativamente simple. En primer lugar, crear el proveedor de filtro:

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

Y luego aplicarlo:

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

Tenga en cuenta que un nuevo atributo se ha añadido en ASP.NET MVC 4.0 que hace exactamente eso:
[AllowAnonymous]

Cuestiones relacionadas