【发布时间】:2022-01-13 14:55:47
【问题描述】:
我已经做了很多搜索,但没有找到答案。我在使用 IOpenIddictScopeManager 和 IOpenIddictApplicationManager 时遇到错误,关于使用依赖注入处理连接的连接。
以下是错误:
无法访问已处置的对象。此错误的一个常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文上调用 Dispose() 或将上下文包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。
堆栈跟踪:
System.ObjectDisposedException
HResult=0x80131622
Message=Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'IdentDbContext'.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__54.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at OpenIddict.EntityFrameworkCore.OpenIddictEntityFrameworkCoreScopeStore`3.<CreateAsync>d__14.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at OpenIddict.Core.OpenIddictScopeManager`1.<CreateAsync>d__15.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()
at OpenIddict.Core.OpenIddictScopeManager`1.<CreateAsync>d__16.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at OpenIddict.Core.OpenIddictScopeManager`1.<OpenIddict-Abstractions-IOpenIddictScopeManager-CreateAsync>d__47.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at IdentityApi.WebApi.Controllers.OpenIDManagementController.<CreateScopeAsync>d__4.MoveNext() in E:\Source\Workspaces\Identity\IdentityApi\IdentityApi.WebApi\Controllers\OpenIDManagementController.cs:line 45
This exception was originally thrown at this call stack:
[External Code]
IdentityApi.WebApi.Controllers.OpenIDManagementController.CreateScopeAsync(IdentityApi.WebApi.Models.AdministrationModels.ScopePostInputModel, System.Threading.CancellationToken) in OpenIDManagementController.cs
在我的控制器中,我有以下引发错误的构造函数和方法:
private readonly IOpenIddictApplicationManager _applicationManager;
private readonly IOpenIddictScopeManager _scopeManager;
public OpenIDManagementController(IOpenIddictApplicationManager applicationManager, IOpenIddictScopeManager scopeManager)
{
_applicationManager = applicationManager;
_scopeManager = scopeManager;
}
// Create a scope
[HttpPost("CreateScopeAsync", Name = nameof(CreateScopeAsync))]
public async void CreateScopeAsync(ScopePostInputModel scopeInput, CancellationToken cancellationToken)
{
if (await _scopeManager.FindByNameAsync(scopeInput.Name, cancellationToken) is null)
{
var scopeToAdd = new OpenIddictScopeDescriptor
{
Name = scopeInput.Name,
Description = scopeInput.Description,
DisplayName = scopeInput.DisplayName
};
var createResult = await _scopeManager.CreateAsync(scopeToAdd, cancellationToken); // This errors out for dependancy injection
}
else
{
// error here
}
}
这是我的 Statup.cs 的配置部分:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddRazorPages();
services.AddDbContext<IdentDbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("IdentityDB"));
options.UseOpenIddict();
});
services.AddIdentity<ApplicationUsers, ApplicationRoles>(config =>
{
config.SignIn.RequireConfirmedEmail = true;
config.SignIn.RequireConfirmedAccount = true;
config.User.RequireUniqueEmail = true;
config.Lockout.MaxFailedAccessAttempts = 3;
}).AddEntityFrameworkStores<IdentDbContext>()
.AddUserStore<ApplicationUserStore>()
.AddRoleStore<ApplicationRoleStore>()
.AddRoleManager<ApplicationRoleManager>()
.AddUserManager<ApplicationUserManager>()
.AddErrorDescriber<ApplicationIdentityErrorDescriber>()
.AddDefaultTokenProviders()
.AddDefaultUI();
services.AddDataLibrary();
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = Claims.Name;
options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
options.ClaimsIdentity.RoleClaimType = Claims.Role;
});
services.AddOpenIddict()
.AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<IdentDbContext>();
})
.AddServer(options =>
{
options.AllowClientCredentialsFlow()
.AllowAuthorizationCodeFlow()
.RequireProofKeyForCodeExchange();
options.SetAuthorizationEndpointUris("/api/Authorization/Authorize")
.SetTokenEndpointUris("/Token");
options.RegisterScopes(Scopes.OpenId, Scopes.Email, Scopes.Profile, Scopes.Roles, "DatabaseName");
options.SetIssuer(new Uri(Configuration["Jwt:Issuer"]));
options.AcceptAnonymousClients();
options.DisableAccessTokenEncryption();
options.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate();
options.UseAspNetCore()
.EnableAuthorizationEndpointPassthrough()
.EnableTokenEndpointPassthrough();
})
.AddValidation(options =>
{
options.UseLocalServer();
options.UseAspNetCore();
});
services.AddHostedService<TestData>(); // For development only.
}
我不确定我错过了什么,但无论我做了什么更改,我仍然收到相同的错误。有关如何纠正此错误的任何想法?
【问题讨论】:
-
async void似乎是这里的问题。为什么你使用它而不是返回一个动作结果?当您的代码到达第二次调用时,该操作已超出范围,因为async void方法已被触发并忘记。框架不会等待请求被正确处理。
标签: c# asp.net-core dependency-injection openiddict