asp.net-mvc-3 - paginacion - filtro de busqueda mvc
Atributo de vinculación de Ninject para filtrar con argumentos del constructor (2)
Lo he descubierto (gracias a las instrucciones y documentación de Remo).
Use la extensión .WithConstructorArgument apropiada si está enlazando a un controlador o filtro de acción. Por ejemplo, el enlace de mi filtro de acción se ve así:
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<RequireRolesAttribute>()
.WithConstructorArgumentFromActionAttribute<RequireRolesAttribute>("requiredRoles", o => o.RequiredRoles);
Una vez que entendí la firma Func <> , todo quedó claro. La mejor manera que encontré para manejar esto fue
hacer la extensión de tipo específico para mi atributo
.WithConstructorArgumentFromActionAttribute<TAttribute>()
obtener el valor del objeto de devolución de llamada (su atributo) a través de lambda:
("argumentName", o => o.PropertyName)
Leí tantas respuestas como pude para esto, pero parece que faltan un detalle.
El problema es que al vincular un filtro de acción (con un servicio inyectado por el controlador) a un atributo correspondiente, no he podido averiguar cómo pasar valores de parámetros / propiedades del atributo a su filtro enlazado. A continuación se muestra el código, y debajo de ese mi código falso previsto:
Filtro y Atributo
public class AuthorizationFilter : IAuthorizationFilter
{
private readonly IAuthorizationService _authorizationService;
private readonly UserRoles _requiredRoles; // Enum
public AuthorizationFilter(IAuthorizationService authorizationService, UserRoles requiredRoles)
{
_authorizationService = authorizationService;
_requiredRoles = requiredRoles;
}
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Session == null)
HandleUnauthorizedRequest(filterContext);
else {
var authorized = _authorizationService.IsUserInRole((UserSessionInfoViewModel) filterContext.HttpContext.Session["user"], _requiredRoles);
if (!authorized)
HandleUnauthorizedRequest(filterContext);
// else TODO: deal with cache...
}
}
}
public class RequireRolesAttribute : FilterAttribute
{
public readonly UserRoles RequiredRoles;
public RequireRolesAttribute(UserRoles requiredRoles)
{
RequiredRoles = requiredRoles;
}
}
Filtros / Atributos de enlaces
kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0)
.WhenControllerHas<RequireRolesAttribute>();
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<RequireRolesAttribute>();
Esto debería asegurar que cualquier controlador / acción decorado con [RolesRequired] esté vinculado al filtro. Hasta ahora tan bueno. Ahora quiero declarar a través del atributo los roles (al igual que el AutorizeAttribute) y pasar esos valores al filtro que realmente hace la autorización.
Código previsto / falso:
[RequireRoles(UserRoles.Author)]
public ActionResult Index()
{
// blah
}
Específicamente,
¿Qué se necesita para informar a AuthorizationFilter de los roles? ¿Puede el filtro / ninject acceder a los argumentos pasados al constructor del atributo? ¿Puede el filtro / ninject sacarlos de los atributos de propiedad pública?
Para referencia, estos artículos fueron de gran ayuda, pero no responda a esto:
Inyección de dependencia con atributo Ninject y filtro para asp.net mvc
Autorización personalizada MVC 3 y Ninject IoC
BZ, Remo Gloor, otros ... ¿cómo puedo lograr esto?
y para llevar el método de extensión BindFilter
al alcance, no se olvide de agregar;
using Ninject.Web.Mvc.FilterBindingSyntax;