在ActionFilter中间件中使用DbContext

use*_*109 4 c# asp.net-core-mvc asp.net-core asp.net-core-2.0 ef-core-2.0

我想DbContext在我的ActionFilter中间件中使用a .可能吗?

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");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是这段代码using (var context = new SamuraiDbContext())需要传递选项.我应该再次通过DbContextOptionsBuilder()这里还是有其他办法吗?

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

Kir*_*kin 9

SamuraiDbContext您可以在Filter中使用依赖注入,而不是尝试创建自己的新实例.为了实现这一目标,您需要做三件事:

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

    private readonly SamuraiDbContext dbContext;
    
    public VerifyProfile(SamuraiDbContext dbContext)
    {
        this.dbContext = dbContext;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 添加VerifyProfile到DI容器中.

    services.AddScoped<VerifyProfile>();
    
    Run Code Online (Sandbox Code Playgroud)
  3. 用于ServiceFilter将过滤器连接到DI容器.

    [ServiceFilter(typeof(VerifyProfile))]
    public IActionResult YourAction()
        ...
    
    Run Code Online (Sandbox Code Playgroud)

您可以ServiceFilter在操作级别应用该属性,如图所示,或在控制器级别.您也可以在全球范围内应用它.如果您想这样做,可以使用以下内容替换上面的步骤3:

services.AddMvc(options =>
{
    options.Filters.Add<VerifyProfile>();
});
Run Code Online (Sandbox Code Playgroud)

作为一个额外的资源,这篇博客文章很好地写了一些其他选项.