Asp.net-Mvc-3
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 角色需要什麼?過濾器/注入器可以訪問傳遞給屬性建構子的參數嗎?過濾器/注入器可以從屬性公共屬性中提取它們嗎?
作為參考,這些文章有很大幫助,但不要回答這一件事:
asp.net mvc 的 Ninject 和 Filter 屬性的依賴注入
BZ,Remo Gloor,其他人……我該如何做到這一點?
我已經弄清楚了(感謝 Remo 的指示和文件)。
無論您是綁定到 Controller 還是 Action 過濾器,都使用適當的**.WithConstructorArgument擴展。**例如綁定我的動作過濾器如下所示:
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0) .WhenActionMethodHas<RequireRolesAttribute>() .WithConstructorArgumentFromActionAttribute<RequireRolesAttribute>("requiredRoles", o => o.RequiredRoles);一旦我理解了**Func<>**簽名,一切就變得清晰了。我發現處理這個問題的最好方法是
- 使擴展類型特定於我的屬性
.WithConstructorArgumentFromActionAttribute<TAttribute>()
- 通過 lambda 從回調對象(您的屬性)中獲取值:
("argumentName", o => o.PropertyName)