ASP.NET MVC3 + ActionFilterAttribute + iniezione?
-
27-10-2019 - |
Domanda
Ehi, io di successo sono stato in grado di iniezione di proprietà uso nel mio FilterAttribute, però mi chiedo se la sua possibile spostarlo al costruttore, invece?
Il mio codice corrente:
// AuthAttribute.cs
public class AuthAttribute : ActionFilterAttribute
{
public Roles _authRoles { get; private set; }
[Inject]
private readonly IAuthorizationService _service;
public AuthAttribute(Roles roles)
{
_authRoles = roles;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;
string redirectUrl = string.Format("?returnUrl={0}", redirectOnSuccess);
string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
else
{
bool isAuthorized = _service.Authorize(GetUserSession.Id, _authRoles.ToString());
if (!isAuthorized)
{
// TODO: Make custom "Not Authorized" error page.
throw new UnauthorizedAccessException("No access");
}
}
}
}
// TestController.cs
[Auth(Roles.Developer)]
public ActionResult Index()
{
// Some smart logic
}
Grazie in anticipo!
Soluzione
No, questo non è possibile in quanto i parametri per i costruttori deve essere tipi semplici .
Ai fini della prova, si potrebbe avere un altro costruttore (dal momento che non dovrebbe usare un contenitore CIO con test):
public class AuthAttribute : ActionFilterAttribute
{
public Roles _authRoles { get; private set; }
[Inject]
private readonly IAuthorizationService _service;
public AuthAttribute(Roles roles)
{
_authRoles = roles;
}
public AuthAttribute(Roles roles, IAuthorizationService authSvc)
: this(roles)
{
this.service = authSvc;
}
// ...
}
Altri suggerimenti
iniezione Constructor è possibile in questo scenario, ma è necessario utilizzare una combo attributo / filtro.
Il filtro (es:. IAuthorizationFilter) implementazione useranno Constructor Iniezione e fare tutto il lavoro ...
l'attributo (es:. FilterAttribute). Sarà sottile, utilizzato principalmente per decorare i vostri controller o azioni
public class AuthorizationFilter : IAuthorizationFilter
{
private readonly IAuthorizationService _authorizationService;
private readonly UserRoles _requiredRoles; // Enum of Roles
public AuthorizationFilter(IAuthorizationService authorizationService, UserRoles requiredRoles)
{
_authorizationService = authorizationService;
_requiredRoles = requiredRoles;
}
public void OnAuthorization(AuthorizationContext filterContext)
{
// do work, or HandleUnauthorizedRequest()
}
protected void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// do work
}
}
public class RequireRolesAttribute : FilterAttribute
{
public readonly UserRoles RequiredRoles;
public RequireRolesAttribute(UserRoles requiredRoles)
{
RequiredRoles = requiredRoles;
}
}
Quindi il vostro contenitore Ninject si lega l'attributo al filtro:
// controller-level
kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0).WhenControllerHas<RequireRolesAttribute>()
// action level
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0).WhenActionMethodHas<RequireRolesAttribute>();
Si veda:
Dependency Injection con Ninject e attributo di filtro per asp.net mvc
Ninject Binding attributo di filtro con il costruttore Argomenti
https://github.com/ninject/ninject.web .mvc / wiki / Filter-configurazioni
Il trucco che sto cercando di superare è come ottenere i miei ruoli definiti sulla attributo per il filtro ... la documentazione Ninject dovrebbe aiutare ma non sono ancora arrivati ??me stesso.
In bocca al lupo.