自定义授权MVC 3和Ninject IoC

B Z*_*B Z 10 asp.net-mvc ninject asp.net-mvc-3

我有一个自定义授权类,它继承自FilterAttribute并实现IAuthorizationFilter.我正在使用最新版本的Ninject w/asp.net MVC 3支持.

我遇到的问题是我使用构造函数注入来注入存储库.但是在调用OnAuthorization时,存储库为null.这是代码......

public class MyAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
    {
        private readonly IMyRepo _MyRepo;

        public MyAuthorizeAttribute() { }
        public MyAuthorizeAttribute(IMyRepo myRepo)
        {
            _MyRepo= myRepo; //this gets initialized
        }


        public void OnAuthorization(AuthorizationContext filterContext)
        {
            _MyRepo.DoStuff(); //<< Null, wtf

        }
    }
Run Code Online (Sandbox Code Playgroud)

过滤器绑定:

Bind<IMyRepo>().To<MyRepo>().InRequestScope();


this.BindFilter<MyAuthorizeAttribute >(System.Web.Mvc.FilterScope.Controller, null).WhenControllerHas<MyAuthorizeAttribute >();
Run Code Online (Sandbox Code Playgroud)

更新: 我注意到的一件事是这个过滤器处于控制器级别.我在行动范围内有其他过滤器似乎正常工作......这可能是原因吗?

更新2: 我已经确认,如果我将过滤器范围更改为action,则存储库可用OnAuthorization(非null).

这在下面工作,但我需要在控制器范围,而不是行动.

this.BindFilter<MyAuthorizeAttribute >(System.Web.Mvc.FilterScope.Action, null).WhenActionMethodHas<MyAuthorizeAttribute >();
Run Code Online (Sandbox Code Playgroud)

Rem*_*oor 10

属性不支持构造函数注入,因为它们是由.NET Framework创建的,并且不受Ninject的控制.如果你真的想使用FilterAttribute(我不推荐),你将不得不使用属性注入.

而是继续你刚刚开始的.您需要一个实现IAuthorizationFilter的过滤器(不是从FilterAttribute派生,只是从上面的代码中删除它),另外还需要一个普通的属性来标记控制器/动作.

然后更改绑定:

this.BindFilter<MyAuthorizeFilter>(FilterScope.Controller, 0).WhenControllerHas<MyAuthorizeAttribute>();
Run Code Online (Sandbox Code Playgroud)

请参阅:https://github.com/ninject/ninject.web.mvc/wiki/MVC3

您当前实现的问题是它被发现一次作为过滤器属性并且一旦被添加为普通过滤器.对于这些实例,一个将注入repo,另一个repo为null.

注意:如果这样可以简化您的实现,则可以从现有的FilterAttribute派生.但是在这种情况下不要将它用作属性,而是将其用作普通过滤器.


Roh*_*est 6

最好扩展AuthorizeAttribute类,以便授权可以正常使用缓存的请求.您还需要使用Ninject.Web.Mvc

您需要使用Ninject属性注入来使用您的存储库.构造函数注入不适用于Attributes.

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    [Inject]
    public IMyRepo MyRepo { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return base.AuthorizeCore(httpContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这是我原来的,但后来开始收到一些""基础提供商失败的开放"EF的例外... dunno,如果他们与使用授权过滤器有关,所以我决定尝试ctor注入,在这里我上午... (2认同)