在ActionFilter中间件中使用DbContext

时间:2018-04-26 10:45:44

标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.0 ef-core-2.0

我想在ActionFilter中间件中使用DbContext。有可能吗?

public class VerifyProfile : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        using (var context = new SamuraiDbContext())
        {
            var user = filterContext.HttpContext.User.Identity.Name;
            if (context.Profiles.SingleOrDefaultAsync(p => p.IdentityName == user).Result == null)
            {
                filterContext.Result = new RedirectResult("~/admin/setup");
            }
        }
    }
}

但是此代码using (var context = new SamuraiDbContext())需要传递选项。我是否应该再次通过DbContextOptionsBuilder()或者还有其他方式吗?

我想在我的控制器方法中使用[VerifyProfile]属性。有可能吗?

1 个答案:

答案 0 :(得分:6)

您可以在过滤器中使用Dependency Injection,而不是尝试自己创建SamuraiDbContext的新实例。为了实现这一目标,您需要做三件事:

  1. VerifyProfile添加构造函数,该构造函数接受SamuraiDbContext类型的参数并将其存储为字段。

    private readonly SamuraiDbContext dbContext;
    
    public VerifyProfile(SamuraiDbContext dbContext)
    {
        this.dbContext = dbContext;
    }
    
  2. VerifyProfile添加到DI容器中。

    services.AddScoped<VerifyProfile>();
    
  3. 使用ServiceFilter负责将过滤器连接到DI容器。

    [ServiceFilter(typeof(VerifyProfile))]
    public IActionResult YourAction()
        ...
    
  4. 您可以在操作级别应用ServiceFilter属性,如图所示,或在控制器级别应用。您也可以在全球范围内应用它。如果您想这样做,可以使用以下内容替换上面的步骤3:

    services.AddMvc(options =>
    {
        options.Filters.Add<VerifyProfile>();
    });
    

    作为一项额外资源,this blog post可以很好地编写其他一些选项。