@@abp console project System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance 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 instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
System.ObjectDisposedException: Cannot access a disposed context instance #1753
1
Mohammad created 2 years ago
Hello
I am getting this error when I try to use a EF Core Repository which is resolved using ServiceProvider in CustomTenantResolver.
System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance 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 instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
If you're creating a bug/problem report, please include followings:
ABP Framework version: v4.3.2
UI type: Angular
DB provider: EF Core
Tiered (MVC) or Identity Server Separated (Angular): yes
Exception message and stack trace:
Steps to reproduce the issue:"
8 Answer(s)
0
EngincanV created 2 years ago
Support Team
Hi @Mohammad, can you share where you used the repository (for example, your application service method)?
0
Mohammad created 2 years ago
Hi
I am using it in Custom Tenant Resolver.
publicclassAccessTokenTenantResolver : HttpTenantResolveContributorBase
{
publicoverridestring Name => "AccessToken";
protectedoverrideasync Task GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext)
{
IClientCredentialRepository clientCredentialRepository = context.ServiceProvider.GetRequiredService();
string accessCode = httpContext.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(accessCode))
{
var token = accessCode.Split(" ")[1];
var tokenHandler = new JwtSecurityTokenHandler();
var tokens = tokenHandler.ReadJwtToken(token);
var client_id = tokens.Claims.FirstOrDefault(x => x.Type == "client_id").Value;
var scopes = tokens.Claims.FirstOrDefault(x => x.Type == "scope").Value;
if (scopes.Contains("Scope"))
{
var client = await clientCredentialRepository.SingleOrDefaultAsync(x => x.ClientId == client_id);
if (client == null)
returnawait Task.FromResult(null);
returnawait Task.FromResult(client.TenantId.Value.ToString());
}
}
returnawait Task.FromResult("37fb7b60-0ba6-8109-70b1-a049e5f25575");
}
}
0
EngincanV created 2 years ago
Support Team
Can you add the [UnitOfWork] attribute to above of your method and try it again?
0
Mohammad created 2 years ago
I am getting the same error even after adding [UnitOfWork]
2021-08-2316:01:08.732 +03:00 [WRN] System.ObjectDisposedException: Cannot access a disposed contextinstance. A common cause of this error is disposing a contextinstance that was resolved from dependency injection and then later trying to use the same contextinstance elsewhere in your application. This may occur if you are calling 'Dispose' on the contextinstance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing contextinstances.
Object name: 'ClientManagementDbContext'.
at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_ChangeTracker()
at Microsoft.EntityFrameworkCore.Query.CompiledQueryCacheKeyGenerator.GenerateCacheKeyCore(Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.RelationalCompiledQueryCacheKeyGenerator.GenerateCacheKeyCore(Expression query, Boolean async)
at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlCompiledQueryCacheKeyGenerator.GenerateCacheKey(Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, LambdaExpression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.SingleOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate, CancellationToken cancellationToken)
at Zenithr.Tenant.Shared.AccessTokenTenantResolver.GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext) in C:\websites\ZENITHR3.0\Zenithr.Shared.Tenant\AccessTokenTenantResolver.cs:line 43at Volo.Abp.AspNetCore.MultiTenancy.HttpTenantResolveContributorBase.ResolveFromHttpContextAsync(ITenantResolveContext context, HttpContext httpContext)
at Volo.Abp.AspNetCore.MultiTenancy.HttpTenantResolveContributorBase.ResolveAsync(ITenantResolveContext context)
1
maliming created 2 years ago
Support Team
hi Mohammad
Can you try this:
using (var uow = _unitOfWorkManager.Begin()
{
var client = await clientCredentialRepository.SingleOrDefaultAsync(x => x.ClientId == client_id);
await uow.CompleteAsync();
}
1
Mohammad created 2 years ago
the using statement worked.
Why do I need to do the using for Unitofwork for the repository to work? can you explain? Is this a workaround or an actual solution?
1
maliming created 2 years ago
Support Team
hi
The GetTenantIdOrNameFromHttpContextOrNullAsync method not in a uow because the middleware order.
And the AccessTokenTenantResolver is created by new instead of DI, so the [UnitOfWork] won't work
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2022-06-30 .Net Core之发送邮件
2022-06-30 .Net Core之后台任务
2021-06-30 .Net Core with 微服务 - Elastic APM
2021-06-30 .Net EF Core千万级数据实践
2021-06-30 十八、.net core(.NET 6)搭建ElasticSearch(ES)系列之使用Logstash通过Rabbitmq接收Serilog日志到ES
2021-06-30 【spring源码系列】之【Bean的生命周期】
2021-06-30 手摸手,带你用Beego撸商城系列一(基础篇)