Asp.net-Mvc-3

Ninject 綁定屬性以使用建構子參數進行過濾

  • July 16, 2012

我為此閱讀了盡可能多的答案,但它們似乎缺少一個細節。

問題是當將動作過濾器(通過控制器注入的服務)綁定到相應的屬性時,我無法弄清楚如何將參數/屬性值從屬性傳遞到其綁定過濾器。下面是程式碼,下面是我想要的假程式碼:

過濾器和屬性

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 角色需要什麼?過濾器/注入器可以訪問傳遞給屬性建構子的參數嗎?過濾器/注入器可以從屬性公共屬性中提取它們嗎?

作為參考,這些文章有很大幫助,但不要回答這一件事:

asp.net mvc 的 Ninject 和 Filter 屬性的依賴注入

自定義授權 MVC 3 和 Ninject IoC

BZ,Remo Gloor,其他人……我該如何做到這一點?

我已經弄清楚了(感謝 Remo 的指示和文件)。

無論您是綁定到 Controller 還是 Action 過濾器,都使用適當的**.WithConstructorArgument擴展。**例如綁定我的動作過濾器如下所示:

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

一旦我理解了**Func<>**簽名,一切就變得清晰了。我發現處理這個問題的最好方法是

  1. 使擴展類型特定於我的屬性
.WithConstructorArgumentFromActionAttribute&lt;TAttribute&gt;()
  1. 通過 lambda 從回調對象(您的屬性)中獲取值:
("argumentName", o =&gt; o.PropertyName)

引用自:https://stackoverflow.com/questions/8305476