2011-11-29 120 views
14

我讀儘可能多的答案,因爲我能爲這個過濾器,但他們似乎功虧一簣一個細節。Ninject綁定屬性與構造函數參數

麻煩的是結合一個動作過濾器(具有由控制器注射服務)到相應的屬性,我已經無法找出如何從屬性到其綁定的濾波器通參數/屬性值時。下面是代碼,並低於我的預期僞代碼:

過濾&屬性

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

過濾/屬性綁定

kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0) 
     .WhenControllerHas<RequireRolesAttribute>(); 
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0) 
     .WhenActionMethodHas<RequireRolesAttribute>(); 

這應確保任何控制器/用[RolesRequired]裝飾的動作綁定到過濾器。到現在爲止還挺好。現在我想通過屬性聲明角色(很像股票AuthorizeAttribute)並將這些值傳遞給實際執行授權的過濾器。

擬/假代碼:

[RequireRoles(UserRoles.Author)] 
public ActionResult Index() 
{ 
    // blah 
} 

具體來說,

怎樣才能告知角色的AuthorizationFilter? filter/ninject可以訪問傳遞給屬性構造函數的參數嗎?過濾器/ ninject是否可以將它們從屬性公共屬性中拉出來?

供參考,這些文章是一個巨大的幫助,但不回答這樣一兩件事:

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

Custom Authorization MVC 3 and Ninject IoC

BZ,雷莫Gloor,其他...我怎麼能做到這個?

回答

19

我已經想通了(感謝聖雷莫的方向和文檔)。

使用適當的.WithConstructorArgument擴展名是否綁定到Controller或Action過濾器。例如結合我的行爲過濾器看起來像這樣:

kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0) 
     .WhenActionMethodHas<RequireRolesAttribute>() 
     .WithConstructorArgumentFromActionAttribute<RequireRolesAttribute>("requiredRoles", o => o.RequiredRoles); 

一旦我明白了Func鍵<>簽名,這一切都變得清晰。最好的辦法,我發現處理這是

  1. 使擴展型特異性爲我的屬性

    .WithConstructorArgumentFromActionAttribute<TAttribute>() 
    
  2. 通過拉姆達獲取從回調對象(您的屬性)值:

    ("argumentName", o => o.PropertyName) 
    
+1

只是門票,歡呼聲 – redsquare

+0

任何想法,什麼都有,如果從類派生要做'FilterAttribute'有多個參數(即RequireRoles在具有多個指標的影響構造上面的例子類)構造函數那麼如何才能參數映射到'.WithConstructorArgumentFromActionAttribute ()'? – Vipresh

+1

要使'BindFilter <>()'方法可用,您可以添加對'Ninject.Web.Mvc.FilterBindingSyntax'的引用。 – bump

8

,並帶來了BindFilter擴展方法爲範圍不要忘記添加;

using Ninject.Web.Mvc.FilterBindingSyntax; 
+15

這不是一個答案,它應該發佈爲解答的評論。 – angularsen

+0

儘管這個鏈接可能回答這個問題,但最好在這裏包含答案的基本部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/ review/low-quality-posts/18739473) – diceler

相關問題