我刚刚将.NET Core 2.0迁移到.NET Core 2.1。一切都很顺利,但是当我尝试登录时,我得到了以下错误:
- $ exception {System.ObjectDisposedException:无法访问已处置的对象。 对象名称:' IServiceProvider'。
在这段代码中会发生这种情况:
public class AppContractResolver : DefaultContractResolver
{
private readonly IServiceProvider _services;
public AppContractResolver(IServiceProvider services)
{
_services = services;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var httpContextAccessor = _services.GetService<IHttpContextAccessor>();
var user = httpContextAccessor.HttpContext.User;
List<JsonProperty> properies = base.CreateProperties(type, memberSerialization).ToList();
properies = FilterOneClaimGranted(type, properies, user);
return properies;
}
它发生在这一行:
var httpContextAccessor = _services.GetService<IHttpContextAccessor>();
这适用于.NET Core 2.0
我尝试将HttpContextAccessor
添加到我的启动中,但这不起作用。
那么,我该如何解决这个问题?
如果您需要更多代码,请与我们联系。我很乐意提供更多,但我不知道你可能需要什么或不需要什么,所以我没有添加很多代码。&#39;
编辑
我已将services.AddHttpContextAccessor();
添加到我的初创公司,但这似乎不起作用。仍然得到错误。
编辑2:
完整的堆栈跟踪:
- $exception {System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IServiceProvider'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at WebAPI.Extensions.AppContractResolver.CreateProperties(Type type, MemberSerialization memberSerialization) in C:\Users\luukw\Desktop\stage\blacky-api\Blacky\Extensions\Resolver\AppContractResolver.cs:line 25
at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(Type objectType)
at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.GetContractSafe(Type type)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Microsoft.AspNetCore.Mvc.Formatters.JsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)} System.ObjectDisposedException
答案 0 :(得分:10)
在我的案例中,问题出在Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider services)
{
var svc = services.GetService<IService>(); // <-- exception here
}
只需将services.GetService<>()
替换为app.ApplicationServices.GetService<>()
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var svc = app.ApplicationServices.GetService<IService>(); // no exception
}
希望有所帮助
答案 1 :(得分:9)
我建议不要打电话
services.GetService< IHttpContextAccessor>()
,将IHttpContextAccessor
注入构造函数并使用aprivate字段存储值。
public AppContractResolver(IServiceProvider services,
IHttpContextAccessor httpContextAccessor )
{
_services = services;
this.httpContextAccessor =httpContextAccessor ;
}
还必须手动注册HttpContextAccessor。
在Startup.cs中的RegisterServices中添加services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
答案 2 :(得分:2)
我收到了这个错误,花了很长时间才解决,所以我要把它贴在这里。
这是引发错误的代码:
using var context = this.DbFactory.CreateDbContext();
SqlParameter[] parameter =
{
new SqlParameter("@ord_cust_id", ordCustId)
};
products = await context.GetProduct.FromSqlRaw<ProductEntity>($"{spName} @ord_cust_id", parameter).AsNoTracking().ToListAsync();
抛出的异常在最后一行。由于上下文是由 DbFactory 创建的,因此没有任何意义,因此无法处理它。
找了好久,发现DbFactory的作用域是“Transient”,改成Singleton,异常解决。
这是启动时的代码:
services.AddDbContextFactory<CDSEntities>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
}, ServiceLifetime.Singleton); //changed to Singlton instead of Transient
答案 3 :(得分:1)
对我来说,它适用于:
public void ConfigureServices(IServiceCollection services)
{
…
services.AddHttpContextAccessor();
…
}
然后:
public void Configure(IApplicationBuilder app, IHttpContextAccessor accessor)
{
...
...accessor.HttpContext.RequestService
...
}
答案 4 :(得分:0)
我认为IServiceProvider
实现可能在某个地方无意中被用于using
语句或被彻底处置。
要测试是否是这种情况,您可以尝试在IHttpContextAccessor
方法之后或之内尝试解析ConfigureServices
。
如果它在那里解决,你需要逐步找出IServiceProvider
被处置的位置。
答案 5 :(得分:0)
如果创建任何临时服务,例如services.AddTransient ...,则.net核心将处置服务提供者。从.net core 2.2开始,这是一个错误。
答案 6 :(得分:0)
尝试在 Startup ➢ ConfigureServices
方法中获取服务时遇到了类似的异常:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<INotification>(provider =>
{
var hubContext = (IHubContext<NotificationHub>)provider
.GetService(typeof(IHubContext<NotificationHub>));
// ↓↓↓ Exception: cannot access a disposed object. Object name: 'IServiceProvider'.
var mediator = (IMediator)provider.GetService(typeof(IMediator));
hubContext.SetListener(() =>
mediator.Send(new ...);
...
});
}
...
}
仅供参考:NotificationHub
是我实现自定义 INotificaiton
服务的自定义通知类。
通过创建本地范围服务解决了问题:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<INotification>(provider =>
{
var hubContext = (IHubContext<NotificationHub>)provider
.GetService(typeof(IHubContext<NotificationHub>));
var myScope = provider.CreateScope(); // <<< creating a scoped sertvice
var mediator = (IMediator)myScope.ServiceProvider.GetService(typeof(IMediator));
hubContext.SetListener(() =>
mediator.Send(new ...);
...
});
}
...
}