Ninject 绑定属性以使用构造函数参数进行过滤 [英] Ninject Binding Attribute to Filter with Constructor Arguments
问题描述
为此我阅读了尽可能多的答案,但似乎缺少一个细节.
I read as many answers as I could for this, but they seem to fall short of one detail.
问题是将动作过滤器(由控制器注入的服务)绑定到相应的属性时,我一直无法弄清楚如何将参数/属性值从属性传递到其绑定过滤器.下面是代码,下面是我想要的假代码:
The trouble is when binding an action filter (with a service injected by controller) to a corresponding attribute, I've been unable to figure out how to pass parameter/property values from the attribute to its bound filter. Below is the code, and below that my intended fake-code:
过滤器&属性
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)并将这些值传递给实际执行授权的过滤器.
This should make sure any controller/action decorated with [RolesRequired] is bound to the filter. So far so good. Now I want to declare via the attribute the roles (much like the stock AuthorizeAttribute) and pass those values onto the filter that actually does the authorization.
预期/伪造代码:
[RequireRoles(UserRoles.Author)]
public ActionResult Index()
{
// blah
}
具体来说,
通知 AuthorizationFilter 角色需要什么?filter/ninject 可以访问传递给属性构造函数的参数吗?过滤器/注入器可以从属性公共属性中提取它们吗?
What does it take to inform the AuthorizationFilter of the roles? Can the filter/ninject access the arguments passed to the attribute's constructor? Can the filter/ninject pull them from the attributes public property?
作为参考,这些文章是一个巨大的帮助,但不要回答这一件事:
For reference, these articles were a huge help, but don't answer this one thing:
具有 Ninject 和 Filter 属性的依赖注入用于 asp.net mvc
B Z、Remo Gloor 和其他人……我怎样才能做到这一点?
B Z, Remo Gloor, others... how can I accomplish this?
推荐答案
我已经想通了(感谢 Remo 的指导和文档).
I have figured it out (thanks to Remo's directions and documentation).
使用适当的 .WithConstructorArgument 扩展,无论您是绑定到控制器还是操作过滤器.例如绑定我的动作过滤器看起来像这样:
Use the appropriate .WithConstructorArgument extension whether you are binding to a Controller or Action filter. For example binding my action filter looks like this:
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<RequireRolesAttribute>()
.WithConstructorArgumentFromActionAttribute<RequireRolesAttribute>("requiredRoles", o => o.RequiredRoles);
一旦我理解了 Func<> 签名,一切就变得清晰了.我发现处理这个问题的最好方法是
Once I understood the Func<> signature, it all became clear. The best way I found to handle this was to
使扩展类型特定于我的属性
make the extension type-specific for my attribute
.WithConstructorArgumentFromActionAttribute<TAttribute>()
通过 lambda 从回调对象(您的属性)中获取值:
fetch the value from the callback object (your attribute) via lambda:
("argumentName", o => o.PropertyName)
这篇关于Ninject 绑定属性以使用构造函数参数进行过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!