自定义授权处理程序中的EF核心数据库上下文注入

时间:2019-10-08 23:45:17

标签: c# asp.net-core entity-framework-core

我需要在自定义授权处理程序中使用实体框架。但这不起作用。它在运行时失败。我在响应正文中收到此错误:

<h2 class="stackerror">InvalidOperationException: Cannot consume scoped service &#x27;SomeDbContext&#x27; from singleton &#x27;Microsoft.AspNetCore.Authorization.IAuthorizationHandler&#x27;.</h2>

我不能像这样注入数据库上下文。如何在自定义授权处理程序中使用数据库上下文?

在我的自定义授权处理程序类中:

public class CustomAuthorizationHandler : AuthorizationHandler<CustomAuthRequirement>
{
    private readonly SomeDbContext _dbContext;

    public CustomAuthorizationHandler(SomeDbContext context)
    {
        _dbContext = context;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthRequirement requirement)
    {
        ...

        //Some datatable read operations with _dbContext

        ...
    }
}

在我的Startup.cs中:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<SomeDbContext>(options =>
              options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection")));

        services.AddSingleton<IAuthorizationPolicyProvider, CustomAuthPolicyProvider>();

        services.AddSingleton<IAuthorizationHandler, CustomAuthorizationHandler>();

        ...
    }

2 个答案:

答案 0 :(得分:1)

您可以将IServiceProvider serviceProvider注入CustomAuthorizationHandler中。尝试使用以下代码:

public class CustomAuthorizationHandler : AuthorizationHandler<CustomAuthRequirement>
{
    private readonly IServiceProvider _serviceProvider;

    public CustomAuthorizationHandler (IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   CustomAuthRequirement requirement)
    {

        using (var scope = _serviceProvider.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService<SomeDbContext>();

            //...
        }
    }
}

答案 1 :(得分:0)

我遇到了同样的问题,事实证明,我需要更改的只是示波器,如果需要的话,在启动时

services.AddTransient<IAuthorizationHandler, CustomAuthorizationHandler>();

它可能会像修复我的代码一样修复它,这样我就不需要添加任何额外的代码