.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
_
services.GetService< IHttpContextAccessor>()
を呼び出す代わりに、IHttpContextAccessor
をコンストラクタに挿入し、aprivateフィールドを使用して値を保存することをお勧めします。
_public AppContractResolver(IServiceProvider services,
IHttpContextAccessor httpContextAccessor )
{
_services = services;
this.httpContextAccessor =httpContextAccessor ;
}
_
また、HttpContextAccessorは手動で登録する必要があります。 Startup.csのRegisterServicesにservices.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
を追加します
私の場合、問題は_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
}
_
それが役に立てば幸い
Services.AddTransient ...などの一時的なサービスを作成すると、.netコアはサービスプロバイダーを破棄します。これは.net core 2.2のバグです。
私にとっては:
public void ConfigureServices(IServiceCollection services)
{
…
services.AddHttpContextAccessor();
…
}
その後:
public void Configure(IApplicationBuilder app, IHttpContextAccessor accessor)
{
...
...accessor.HttpContext.RequestService
...
}
IServiceProvider
の実装がusing
ステートメントで不注意に使用されたか、完全に破棄された可能性があることを想像します。
これが当てはまるかどうかをテストするには、IHttpContextAccessor
メソッドの直後またはその中でConfigureServices
メソッドの解決を試みることができます。
そこで解決する場合は、IServiceProvider
が破棄されている場所を見つけるためにステップスルーする必要があります。