【问题标题】:ASP.NET MVC3 + ActionFilterAttribute + Injection?ASP.NET MVC3 + ActionFilterAttribute + 注入?
【发布时间】:2011-01-29 20:39:31
【问题描述】:

嘿,我已经成功地在我的 FilterAttribute 中使用属性注入,但是我想知道是否可以将它移到构造函数中?

我当前的代码:

// AuthAttribute.cs

public class AuthAttribute : ActionFilterAttribute
{
    public Roles _authRoles { get; private set; }

    [Inject]
    private readonly IAuthorizationService _service;

    public AuthAttribute(Roles roles)
    {
        _authRoles = roles;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;
            string redirectUrl = string.Format("?returnUrl={0}", redirectOnSuccess);
            string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;

            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }
        else
        {
            bool isAuthorized = _service.Authorize(GetUserSession.Id, _authRoles.ToString());

            if (!isAuthorized)
            {
                // TODO: Make custom "Not Authorized" error page.
                throw new UnauthorizedAccessException("No access");
            }
        }
    }
}

 

// TestController.cs

[Auth(Roles.Developer)]
public ActionResult Index()
{
    // Some smart logic
}

提前致谢!

【问题讨论】:

    标签: c# asp.net dependency-injection asp.net-mvc-3 actionfilterattribute


    【解决方案1】:

    不,这不可能作为构造函数must be simple types的参数。

    出于测试目的,您可以使用另一个构造函数(因为您不应该使用 IoC 容器进行测试):

    public class AuthAttribute : ActionFilterAttribute
    {
        public Roles _authRoles { get; private set; }
    
        [Inject]
        private readonly IAuthorizationService _service;
    
        public AuthAttribute(Roles roles)
        {
            _authRoles = roles;
        }
    
        public AuthAttribute(Roles roles, IAuthorizationService authSvc)
            : this(roles)
        {
            this.service = authSvc;
        }
    
        // ...
    }
    

    【讨论】:

    • TheCloudlessSky 在您仅使用属性时是正确的。过滤器可以使用构造函数注入,但是您需要将属性绑定到过滤器......我在下面提供了一个答案;感谢 Remo Gloor、B Z 和其他人的帮助。
    【解决方案2】:

    构造函数注入在这种情况下是可能的,但您需要使用属性/过滤器组合。

    您的过滤器(例如:IAuthorizationFilter)实现将使用构造函数注入并完成所有工作...

    你的属性(例如:FilterAttribute)会很薄,主要用来装饰你的控制器或动作。

    public class AuthorizationFilter : IAuthorizationFilter
    {
        private readonly IAuthorizationService _authorizationService;
        private readonly UserRoles _requiredRoles; // Enum of Roles
    
        public AuthorizationFilter(IAuthorizationService authorizationService, UserRoles requiredRoles)
        {
            _authorizationService = authorizationService;
            _requiredRoles = requiredRoles;
        }
    
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            // do work, or HandleUnauthorizedRequest()
        }
    
        protected void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // do work
        }
    
    }
    
    public class RequireRolesAttribute : FilterAttribute
    {
        public readonly UserRoles RequiredRoles;
    
        public RequireRolesAttribute(UserRoles requiredRoles)
        {
            RequiredRoles = requiredRoles;
        }        
    }
    

    然后你的 Ninject 容器将 Attribute 绑定到 Filter:

    // controller-level
    kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0).WhenControllerHas<RequireRolesAttribute>()
    // action level
    kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0).WhenActionMethodHas<RequireRolesAttribute>();
    

    见:

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

    Ninject Binding Attribute to Filter with Constructor Arguments

    https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations

    我希望克服的技巧是如何将我的角色定义在过滤器的属性上...... ninject 文档应该会有所帮助,但我自己还没有。

    祝你好运。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-15
      • 2021-02-16
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多