10

ちょっと、私はFilterAttributeでプロパティインジェクションを使用することができましたが、代わりにコンストラクタに移すことが可能かどうか疑問です。ASP.NET MVC3 + ActionFilterAttribute + Injection?

私の現在のコード:事前に

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

ありがとう!

答えて

8

いいえ、これはコンストラクタのパラメータとしては不可能ですmust be simple types。テスト目的のために

、あなたは(あなたがテストをIoCコンテナを使用すべきではないので)別のコンストラクタを持つことができます:

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

    // ... 
} 
+0

属性のみを使用すると、CloudlessSkyが正しく機能します。フィルタはコンストラクタインジェクションを使用できますが、フィルタに属性をバインドする必要があります。私は以下の答えを提示しました。 Remo Gloor、B Z、および他の人たちのおかげで助けになりました。 –

7

コンストラクタ・インジェクションは、このシナリオでは可能ですが、使用する必要があります属性/フィルタコンボ

あなたのフィルター(例:。IAuthorizationFilter)コンストラクタ・インジェクションを使用して、すべての作業を行います実装...

あなたの属性(例:。FilterAttribute)は、主に、あなたのコントローラやアクションを飾るために使用される、薄くなります。

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

その後、あなたのNinjectコンテナがフィルターに属性をバインドします

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

参照:

Dependency Injection with Ninject and Filter attribute for asp.net mvc

Ninject Binding Attribute to Filter with Constructor Arguments

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

私が克服しようとしているのは、フィルタに属性で定義されているロールを取得する方法です。ニンドドキュメントが役立つはずですが、私はまだ自分自身ではありません。

幸運。