【问题标题】:Ninject Binding Attribute to Filter with Constructor ArgumentsNinject 绑定属性以使用构造函数参数进行过滤
【发布时间】:2011-11-29 03:29:04
【问题描述】:

我为此阅读了尽可能多的答案,但似乎缺少一个细节。

问题是当将动作过滤器(通过控制器注入的服务)绑定到相应的属性时,我无法弄清楚如何将参数/属性值从属性传递到其绑定过滤器。下面是代码,下面是我想要的假代码:

过滤器和属性

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 角色?过滤器/注入器可以访问传递给属性构造函数的参数吗?过滤器/注入器可以从属性公共属性中提取它们吗?

作为参考,这些文章帮助很大,但不要回答这一件事:

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

Custom Authorization MVC 3 and Ninject IoC

B Z、Remo Gloor、其他人……我怎样才能做到这一点?

【问题讨论】:

    标签: asp.net-mvc-3 dependency-injection attributes filter ninject


    【解决方案1】:

    要将BindFilter 扩展方法带入作用域,不要忘记添加;

    using Ninject.Web.Mvc.FilterBindingSyntax;
    

    【讨论】:

    • 这不是一个答案,它应该作为解决方案答案的评论发布。
    【解决方案2】:

    我已经弄明白了(感谢 Remo 的指示和文档)。

    无论您是绑定到 Controller 还是 Action 过滤器,都使用适当的 .WithConstructorArgument 扩展。例如绑定我的动作过滤器如下所示:

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

    一旦我理解了 Func 签名,一切就变得清晰了。我发现处理这个问题的最好方法是

    1. 为我的属性指定扩展类型

      .WithConstructorArgumentFromActionAttribute<TAttribute>()
      
    2. 通过 lambda 从回调对象(您的属性)中获取值:

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

    【讨论】:

    • 如果派生自 FilterAttribute 的类具有具有多个参数的构造函数(即上面示例中的 RequireRoles 类具有具有多个参数的构造函数),那么关于如何映射参数的任何想法在.WithConstructorArgumentFromActionAttribute&lt;TAttribute&gt;() ??
    • 要使BindFilter&lt;&gt;() 方法可用,您可以添加对Ninject.Web.Mvc.FilterBindingSyntax 的引用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2023-03-24
    • 1970-01-01
    • 2018-03-27
    • 2012-05-29
    相关资源
    最近更新 更多