web-dev-qa-db-ja.com

サポートされていない.Net Core 3.0の可能なオブジェクトサイクルが検出されました

1対多に関連する2つのエンティティがあります

public class Restaurant {
   public int RestaurantId {get;set;}
   public string Name {get;set;}
   public List<Reservation> Reservations {get;set;}
   ...
}
public class Reservation{
   public int ReservationId {get;set;}
   public int RestaurantId {get;set;}
   public Restaurant Restaurant {get;set;}
}

APIを使用して予約付きのレストランを取得しようとした場合

   var restaurants =  await _dbContext.Restaurants
                .AsNoTracking()
                .AsQueryable()
                .Include(m => m.Reservations).ToListAsync();
    .....

オブジェクトには相互参照が含まれているため、応答としてエラーが表示されます。 別のモデルを作成する または NewtonsoftJson構成 を推奨する関連する投稿があります==

問題は、別のモデルを作成したくなく、2番目の提案が役に立たなかったことです。循環関係なしにデータをロードする方法はありますか? *

System.Text.Json.JsonException:サポートされていない可能性のあるオブジェクトサイクルが検出されました。これは、サイクルが原因であるか、オブジェクトの深さが最大許容深さ32よりも大きい場合に発生します。System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer 、Int32 originalWriterDepth、Int32 flushThreshold、JsonSerializerOptionsオプション、WriteStack&状態)System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json、Object value、Type inputType、JsonSerializerOptions options、CancellationToken cancelToken)at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJ Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context、Encoding selectedEncoding)のMicrosoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__AsyncFilter、Torker、InvokeArcFilter(T)、Filter [Invoker、Tr:AsyncFilter、Invoker] InFilter [Invoker] InFilter [R] Invoker(T)[Filter] Invoker(T)[Filter] [Invoker] [Filter] [Invoker] [Filter] [Invoker] [Filter] [Invoker] [Filter] [Invoker] [Filter]、Invoker [T]、Filter [Invoker] [Filter]、Invoker [T]、Filter [Invoker] T:フィルターを呼び出す|フィルターを呼び出す| | | | |タスクlastTask、State next、Sco peスコープ、オブジェクトの状態、ブール値isCompleted)at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext [TFilter、TFilterAsync](State&next、Scope&scope、Object& state、Boolean&isCompleted)at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()

*

17
Nazar Pylyp

私は新しいプロジェクトでコードを試しましたが、パッケージをインストールした後、2番目の方法がうまくいくようです Microsoft.AspNetCore.Mvc.NewtonsoftJson 最初に3.0

services.AddControllerWithViews()
    .AddNewtonsoftJson(options =>
    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);

新しいプロジェクトで試して、違いを比較してください。

22
Xing Zou

。NET Core 3.1パッケージMicrosoft.AspNetCore.Mvc.NewtonsoftJsonをインストールします

Startup.csサービスを追加

services.AddControllers().AddNewtonsoftJson(options =>
    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
28
anjoe

起動時にJSONシリアル化オプションの設定を機能させることは、将来同様のケースになる可能性があるため、おそらく好ましい方法です。それまでの間、モデルにデータ属性を追加して、シリアル化されないようにすることもできます: https://www.newtonsoft.com/json/help/html/PropertyJsonIgnore.htm

public class Reservation{ 
    public int ReservationId {get;set;} 
    public int RestaurantId {get;set;} 
    [JsonIgnore]
    public Restaurant Restaurant {get;set;} 
}
3
timur
public class Reservation{ 
public int ReservationId {get;set;} 
public int RestaurantId {get;set;} 
[JsonIgnore]
public Restaurant Restaurant {get;set;} 

上記も働いた。しかし、私は以下を好む

services.AddControllers().AddNewtonsoftJson(options =>
    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);

最初に、すべてのモデルに属性を追加する必要があるため、循環参照がある場合があります。

1
Nantharupan