Frage

Hey, ich war erfolgreich in der Lage, die Injektion von Eigenschaften in meinem Filterattribute zu verwenden, aber ich frage mich, ob es möglich ist, sie in den Konstruktor zu bewegen.

Mein aktueller Code:

// 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
}

Danke im Voraus!

War es hilfreich?

Lösung

Nein, dies ist nicht möglich, da die Parameter für die Konstruktoren Muss einfache Typen sein.

Zu den Testzwecken können Sie einen anderen Konstruktor haben (da Sie mit Tests keinen IOC -Container verwenden sollten):

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

    // ...
}

Andere Tipps

Konstruktorinjektion ist In diesem Szenario möglich, aber Sie müssen eine Attribut-/Filter -Kombination verwenden.

Ihre Implementierung von Filter (Ex.: IAutorizationFilter) verwendet die Konstruktorinjektion und erledigt alle Arbeiten ...

Ihr Attribut (z.

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

Dann bindet Ihr Ninject Container das Attribut an den Filter:

// controller-level
kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0).WhenControllerHas<RequireRolesAttribute>()
// action level
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0).WhenActionMethodHas<RequireRolesAttribute>();

Sehen:

Abhängigkeitsinjektion mit Ninjekt- und Filterattribut für ASP.NET MVC

Ninject -Bindungsattribut zum Filter mit Konstruktorargumenten

https://github.com/ninject/ninject.web.mvc/wiki/filter-configurations

Der Trick, den ich überwinden möchte, ist, wie meine Rollen auf dem Attribut zum Filter definiert werden ... Die Ninject -Dokumentation sollte helfen, aber ich bin noch nicht da.

Viel Glück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top