在 ActionFilter 中间件中使用 DbContext

Use DbContext in ActionFilter Middleware

我想在我的 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] 属性。可不可以?

与其尝试自己创建 SamuraiDbContext 的新实例,不如在过滤器中使用 Dependency Injection。为此,您需要做三件事:

  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()
        ...
    

您可以在操作级别(如图所示)或控制器级别应用 ServiceFilter 属性。您也可以在全球范围内应用它。为此,请将上面的步骤 3 替换为以下内容:

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

作为附加资源,this blog post 对其他一些选项进行了很好的描述。