.Net Core 2.1 - Cannot access a disposed object.Ob

2020-02-05 12:04发布

I just migrated .NET Core 2.0 to .NET Core 2.1. Everything went fine, but when I try to login now I get the folowing error:

  • $exception {System.ObjectDisposedException: Cannot access a disposed object. Object name: 'IServiceProvider'.

This happens in this bit of code:

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;
    }

It happens on this line:

var httpContextAccessor = _services.GetService<IHttpContextAccessor>();

This did work on .NET Core 2.0

I have tried adding the HttpContextAccessor to my startup, but that did not work.

So, how do I fix this?

Let me know if you need more code. I will happily provide more, but I don't know what you might or might not need, so therefor I did not add a lot of code.'

EDIT

I have added services.AddHttpContextAccessor(); to my startup, but that does not seem to work. Still getting the error.

EDIT 2:

Full stacktrace:

- $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
5条回答
姐就是有狂的资本
2楼-- · 2020-02-05 12:17

In my case issue was in Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider services)
{
   var svc = services.GetService<IService>(); // <-- exception here
}

just replace services.GetService<>() with app.ApplicationServices.GetService<>()

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
   var svc = app.ApplicationServices.GetService<IService>(); // no exception
}

hope it helps

查看更多
Melony?
3楼-- · 2020-02-05 12:21

I would imagine that the IServiceProvider implementation may have been used in a using statement inadvertently somewhere or been disposed outright.

To test if this is the case you could try to resolve the IHttpContextAccessor right after, or in, the ConfigureServices method.

If it resolves there you would need to step through to find out where the IServiceProvider is being disposed.

查看更多
够拽才男人
4楼-- · 2020-02-05 12:37

I would suggest that instead of calling services.GetService< IHttpContextAccessor>(), inject IHttpContextAccessor to the constructor and use aprivate field to store the value.

public AppContractResolver(IServiceProvider services, 
                             IHttpContextAccessor  httpContextAccessor )
{
   _services = services;
   this.httpContextAccessor =httpContextAccessor ;
}

Also HttpContextAccessor has to be registered manually. In RegisterServices in Startup.cs add, services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

查看更多
做自己的国王
5楼-- · 2020-02-05 12:37

For me it works with:

 public void ConfigureServices(IServiceCollection services)
{
  …
  services.AddHttpContextAccessor();
  …
}

and then:

     public void Configure(IApplicationBuilder app, IHttpContextAccessor accessor)
    {
    ...
    ...accessor.HttpContext.RequestService

     ...

    }
查看更多
我欲成王,谁敢阻挡
6楼-- · 2020-02-05 12:39

If you create any transient service, such as services.AddTransient... then .net core will dispose the service provider. This is a bug as of .net core 2.2.

查看更多
登录 后发表回答