【问题标题】:How do I pass in the repository to an authorize attribute in ASP.NET MVC如何将存储库传递给 ASP.NET MVC 中的授权属性
【发布时间】:2009-08-18 08:24:41
【问题描述】:

我是 Castle Windsor,它非常适合控制器构造函数传入正在使用的存储库。

private IStoryRepository Repository;
public StoryController(IStoryRepository Repository)
{
    this.Repository = Repository;                   
}

现在我在管理区域中有一个操作来显示主管理菜单。我使用了一个自定义授权属性,它只会检查登录用户是否是管理员(只是用户表中的 isAdmin 标志)

 [AdminAuthorize]
 public ActionResult Menu()

 private IStoryRepository Repository;
 /// <summary>
 /// Initializes a new instance of the <see cref="AdminAuthorizeAttribute"/> class.
 /// </summary>
 public AdminAuthorizeAttribute(IStoryRepository Repository)
 {
     this.Repository = Repository;
 }

 /// <summary>
 /// Checks if the user is authorised
 /// </summary>
 /// <param name="httpContext">The HTTP context.</param>
 /// <returns>
 ///    <c>true</c> if authorized; otherwise, <c>false</c>.
 /// </returns>
 protected override bool AuthorizeCore(HttpContextBase httpContext)
 {
    return this.Repository.UserIsAdmin(httpContext.User.Identity.Name);
 }

如何让 Castle 像控制器构造函数一样将存储库传递给属性构造函数?

【问题讨论】:

    标签: asp.net-mvc castle-windsor custom-attributes


    【解决方案1】:

    你基本上有两个选择。将过滤器包装在代理中,可以在 here 找到一个很好的例子。

    或者,在您的自定义过滤器中,您可以进行显式容器调用。例如使用 StructureMap(我没有广泛使用过城堡)

    ObjectFactory.GetInstance(IStoryRepository)
    

    可能还有第三种方法是扩展 ActionInvoker 来进行注入,但我不确定如何做到这一点。

    【讨论】:

      【解决方案2】:

      问题在于属性是通过反射构造的,而不是通过可以被拦截并替换为委托给容器的调用的调用。

      有许多方法可用于创建支持 DI 的过滤器,最简单的恕我直言,扩展操作调用程序并覆盖 GetFilters,提供使用属性确定过滤器类型然后解析该类型的实现容器。这种方法的实现可以在 MvcTurbine (http://mvcturbine.codeplex.com/sourcecontrol/changeset/view/37298?projectName=mvcturbine#758440) 中看到。

      【讨论】:

        【解决方案3】:

        为什么不从 Filter 构造函数中的静态工厂方法中获取 IRepository 对象?您只需使用工厂方法以允许 DI 完成其工作。

        DI 将使用您的“网关”方法而不是标准的“构造函数参数”方法。

        【讨论】:

          【解决方案4】:

          我可能值得关注FluentMVC 项目。它允许您在启动时配置属性,并且因为它在引擎盖下使用了 Windsor,所以应该可以轻松地将其注入。例如

          FluentMvcConfiguration.Configure = x => {
                                           x.UsingControllerFactory(new WindsorControllerFactory());                                                                x.WithFilter<HandleErrorAttribute>();
                                           x.WithFilter<AuthorizeAttribute>(
                                               Except
                                                   .For<AccountController>(ac => ac.LogOn())
                                                   .AndFor<AccountController>(ac => ac.LogOn(null, null, false, null))
                                                   .AndFor<HomeController>());
                                       };
          

          上面的代码会将 AuthorizeAttribute 添加到除 Login 和 home 控制器之外的所有操作

          不确定项目的当前状态是什么,但已经使用了几次,对我来说效果很好。

          【讨论】:

            猜你喜欢
            • 2016-03-21
            • 2018-11-23
            • 2020-01-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-03
            相关资源
            最近更新 更多