web-dev-qa-db-ja.com

.Net Core 2.1-破棄されたオブジェクトにアクセスできませんオブジェクト名: 'IServiceProvider'

.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をスタートアップに追加しようとしましたが、うまくいきませんでした。

それで、どうすればこれを修正できますか?

さらにコードが必要な場合はお知らせください。私は喜んでもっと提供しますが、あなたが必要とするかもしれないし、必要としないかもしれないものがわからないので、多くのコードを追加しませんでした。」

[〜#〜] edit [〜#〜]

スタートアップに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
_
18
Luuk Wuijster

services.GetService< IHttpContextAccessor>()を呼び出す代わりに、IHttpContextAccessorをコンストラクタに挿入し、aprivateフィールドを使用して値を保存することをお勧めします。

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

また、HttpContextAccessorは手動で登録する必要があります。 Startup.csのRegisterServicesにservices.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();を追加します

10
Code Name Jack

私の場合、問題は_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
}
_

それが役に立てば幸い

11
Denis Olifer

Services.AddTransient ...などの一時的なサービスを作成すると、.netコアはサービスプロバイダーを破棄します。これは.net core 2.2のバグです。

1
jjxtra

私にとっては:

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

その後:

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

     ...

    }
1
user3198116

IServiceProviderの実装がusingステートメントで不注意に使用されたか、完全に破棄された可能性があることを想像します。

これが当てはまるかどうかをテストするには、IHttpContextAccessorメソッドの直後またはその中でConfigureServicesメソッドの解決を試みることができます。

そこで解決する場合は、IServiceProviderが破棄されている場所を見つけるためにステップスルーする必要があります。

0
Eben Roux