【问题标题】:Dependency injection inside a FilterAttribute in ASP.NET MVC 6ASP.NET MVC 6 中 FilterAttribute 内的依赖注入
【发布时间】:2015-05-07 09:23:47
【问题描述】:

我正在努力使用 ASP.NET MVC 6(beta 4 版本)尝试在 AuthorizationFilterAttribute 类型的控制器过滤器属性中注入服务。

这是服务(它注入了另一个服务)

public class UsersTableRepository
{
    private readonly NeurosgarContext _dbContext;

    public UsersTableRepository(NeurosgarContext DbContext)
    {
        _dbContext = DbContext;
    }

    public ICollection<User> AllUsers
    {
        get
        {
            return _dbContext.Users.ToList();
        }
    }

    //other stuff...
}

这是 Startup 类中用于启用服务的 ConfigureServices 方法

  public void ConfigureServices(IServiceCollection services)
  {
        //...

        services.AddSingleton<NeurosgarContext>(a => NeurosgarContextFactory.GetContext());
        services.AddSingleton<UifTableRepository<Nazione>>();
        services.AddSingleton<UsersTableRepository>();
  }

一个简单的“虚拟”控制器,上面定义了两个过滤器。你可以注意到我已经在这个控制器中通过使用[FromServices]装饰属性完成了DI,它可以工作了。

[Route("[controller]")]
[BasicAuthenticationFilter(Order = 0)]
[BasicAuthorizationFilter("Admin", Order = 1)]
public class DummyController : Controller
{

    [FromServices]
    public UsersTableRepository UsersRepository { get; set; }

    // GET: /<controller>/
    [Route("[action]")]
    public IActionResult Index()
    {
        return View();
    }
}

BasicAuthenticationFilter 中执行相同的 DI 不起作用,并且在运行时 UserRepository 属性是空引用。

public class BasicAuthenticationFilterAttribute : AuthorizationFilterAttribute
{
    [FromServices]
    public UsersTableRepository UsersRepository { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)

    {
        if (!Authenticate(filterContext.HttpContext))
        {
            // 401 Response
            var result = new HttpUnauthorizedResult();
            // Add the header for Basic authentication require
            filterContext.HttpContext.Response.Headers.Append("WWW-Authenticate", "Basic");
            filterContext.Result = result;

            //if (!HasAllowAnonymous(context))
            //{
            //    base.Fail(context);
            //}
        }
    }
    // ...
}

知道如何解决这个问题吗?

【问题讨论】:

    标签: asp.net asp.net-mvc filter dependency-injection


    【解决方案1】:

    here 所述,请避免将依赖项注入到您的属性中。将您的attributes passive 设为@,或将您的属性设为humble object,如here 所述。

    【讨论】:

    • 问题是如果我在过滤器中使用构造函数注入服务我无法拦截属性实例。
    • 那是因为你不应该将依赖注入到你的属性中。请仔细阅读参考文章。
    【解决方案2】:
        var dependencyScope = context.HttpContext.RequestServices;
        var usersRepository = dependencyScope.GetService(typeof(UsersTableRepository)) as UsersTableRepository;
        // usersRepository is now ready to be used
    

    所以您的 BasicAuthenticationFilter 将如下所示:

    public class BasicAuthenticationFilterAttribute : AuthorizationFilterAttribute
    {
        public UsersTableRepository UsersRepository { get; set; }
    
        public override void OnAuthorization(AuthorizationContext filterContext)
    
        {
            var dependencyScope = context.HttpContext.RequestServices;
            UsersRepository = dependencyScope.GetService(typeof(UsersTableRepository)) as UsersTableRepository;
            
            if (!Authenticate(filterContext.HttpContext))
            {
                // 401 Response
                var result = new HttpUnauthorizedResult();
                // Add the header for Basic authentication require
                filterContext.HttpContext.Response.Headers.Append("WWW-Authenticate", "Basic");
                filterContext.Result = result;
    
                //if (!HasAllowAnonymous(context))
                //{
                //    base.Fail(context);
                //}
            }
        }
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      相关资源
      最近更新 更多