one*_*mer 16 attributes dependency-injection ninject filter asp.net-mvc-3
我尽可能多地阅读了这些答案,但它们似乎没有达到一个细节.
问题是当动作过滤器(由控制器注入的服务)绑定到相应的属性时,我一直无法弄清楚如何将参数/属性值从属性传递到其绑定过滤器.下面是代码,下面是我想要的假代码:
过滤器和属性
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;
}
}
Run Code Online (Sandbox Code Playgroud)
过滤器/属性绑定
kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0)
.WhenControllerHas<RequireRolesAttribute>();
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<RequireRolesAttribute>();
Run Code Online (Sandbox Code Playgroud)
这应该确保用[RolesRequired]修饰的任何控制器/动作都绑定到过滤器.到现在为止还挺好.现在我想通过属性声明角色(很像股票AuthorizeAttribute)并将这些值传递给实际执行授权的过滤器.
预期/假冒代码:
[RequireRoles(UserRoles.Author)]
public ActionResult Index()
{
// blah
}
Run Code Online (Sandbox Code Playgroud)
特别,
如何通知AuthorizationFilter角色?filter/ninject可以访问传递给属性构造函数的参数吗?过滤器/ ninject可以从属性公共属性中提取它们吗?
作为参考,这些文章是一个巨大的帮助,但不回答这一点:
asp.net mvc的Ninject和Filter属性的依赖注入
BZ,Remo Gloor,其他......我怎么能做到这一点?
one*_*mer 20
我已经弄明白了(感谢Remo的指示和文档).
使用适当的.WithConstructorArgument扩展,无论您是绑定到Controller还是Action过滤器.例如,绑定我的动作过滤器如下所示:
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<RequireRolesAttribute>()
.WithConstructorArgumentFromActionAttribute<RequireRolesAttribute>("requiredRoles", o => o.RequiredRoles);
Run Code Online (Sandbox Code Playgroud)
一旦我理解了Func <>签名,一切都变得清晰了.我发现处理这个的最好方法是
使我的属性的扩展类型特定
.WithConstructorArgumentFromActionAttribute<TAttribute>()
Run Code Online (Sandbox Code Playgroud)通过lambda从回调对象(您的属性)获取值:
("argumentName", o => o.PropertyName)
Run Code Online (Sandbox Code Playgroud)并将BindFilter
扩展方法纳入范围不要忘记添加;
using Ninject.Web.Mvc.FilterBindingSyntax;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7259 次 |
最近记录: |