.Net Core 3.0 desteklenmeyen olası nesne çevrimi algılandı


22

Birden çok kişiyle ilişkili 2 birimim var

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

Benim api kullanarak rezervasyonları ile restoranlar almaya çalışırsanız

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

Nesneler birbirlerine referanslar içerdiğinden, yanıt olarak hata alıyorum. Ayrı bir model oluşturmanızı veya NewtonsoftJson yapılandırmasını eklemenizi öneren ilgili yayınlar vardır

Sorun, ayrı bir model oluşturmak istemiyorum ve 2. öneri yardımcı olmadı. Döngü ilişkisi olmadan veri yüklemenin herhangi bir yolu var mı? *

System.Text.Json.JsonException: Desteklenmeyen olası bir nesne döngüsü algılandı. Bunun nedeni bir döngü olabilir veya System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected (Int32 maxDepth) öğesinde System.Text.Json.JsonSerializer.Write (Utf8JsonWriter writer) öğesinde izin verilen maksimum derinlikten daha büyükse olabilir. , Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions seçenekleri, WriteStack & state), System.Text.Json.JsonSerializer.WriteAsyncCore (Stream utf8Json, Object değeri, Type inputType, JsonSerializerOptions options, CancellationToken cancellationTokson.Put.Out.Out.Put.Out.Put.Out.Top.For.Tut.Out.Out.Out.Put.Out.Put.Out.Put.Put.Out.Put.Top.Top.For.Tut.Out.Out.Out.Put.Out.TopenTop.For.Tut.Out.Top.For.Out.Out.Out.Out.Out.Out.Out.Out.Out.Opt.Put.Out.Out.Top.Top.For. Microsoft.AspNetCore.Mvc'de WriteResponseBodyAsync (OutputFormatterWriteContext bağlamı, kodlama seçilenEncoding).

*


Rezervasyon sınıfının Restaurant özelliğini görmezden gelmesini isteyin.
Lasse V. Karlsen

6
Gerçekten DB varlıklarınızı doğrudan API'nizden iade etmemelisiniz. API'ya özgü DTO'lar oluşturmayı ve buna göre eşlemeyi öneririm. Bunu yapmak istemediğinizi söylemiştiniz, ancak API ve kalıcılık içlerini ayrı tutmanın genel iyi uygulama olduğunu düşünürdüm.
mackie

"ve 2. öneri yardımcı olmadı" ayrıntıları gerekiyor.
Henk Holterman

"Sorun, ayrı bir model oluşturmak istemememdir." Siz bunu yapmadığınız sürece tasarımınız temelde kusurludur. API, arayüz gibi bir sözleşmedir (kelimenin tam anlamıyla bir uygulama programlama arayüzüdür ). Bir kez yayınlandıktan sonra hiçbir zaman değişmemelidir ve herhangi bir değişiklik, eski sürümle eşzamanlı olarak çalışması gereken yeni bir sürümü gerektirir (bu sürüm, kullanımdan kaldırılacak ve gelecekte kaldırılacaktır). Bu, müşterilerin uygulamalarını güncellemeleri için zaman tanır. Bir varlığı doğrudan döndürürseniz, veri katmanınızı sıkıca bağlarsınız.
Chris Pratt

Bu veri katmanında yapılacak herhangi bir değişiklik, API'da anında ve geri döndürülemez bir değişiklik yapılmasını gerektirir ve bu da tüm istemcileri uygulamalarını güncelleyene kadar hemen keser. Açıkça görülmüyorsa, bu kötü bir şeydir. Kısacası: asla API'den varlık kabul etmeyin veya iade etmeyin. Her zaman DTO'ları kullanmalısınız.
Chris Pratt

Yanıtlar:


32

Kodunuzu yeni bir projede denedim ve Microsoft.AspNetCore.Mvc.NewtonsoftJson paketini yükledikten sonra ikinci yol iyi çalışıyor gibi görünüyor 3.0

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

Yeni bir proje deneyin ve farklılıkları karşılaştırın.


1
Burada önemli bir nokta Microsoft.AspNetCore.Mvc.NewtonsoftJson uygun sürümünü yeniden yüklemek için Bu paket herhangi bir hata ve uyarı olmadan kutunun altında mevcut olduğundan sürümü dikkat etmedi! Cevap için teşekkürler ! Her şey beklediğim gibi çalışıyor!
Nazar Pylyp

1
Sistem json'unun geliştirilmiş performansıyla NewtonsoftJson kullanmamız yanlış değil mi? : /
Marek Urbanowicz

40

.NET Core 3.1 Microsoft.AspNetCore.Mvc.NewtonsoftJson paketini yükleyin

Startup.cs Hizmet ekle

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

1
Yanıtınızı biçimlendirebilir ve bazı ayrıntılar ekleyebilir misiniz? Okunamaz.
Sid

Daha fazla ayrıntı için, kontrol edin: thecodebuzz.com/…
Diego Venâncio

4

Başlangıçta JSON serileştirme seçeneklerinin ayarlanması, muhtemelen benzer durumlara sahip olacağınız için tercih edilen bir yoldur. Bu arada, serileştirilmemesi için modelinize veri özellikleri eklemeyi deneyebilirsiniz: 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;} 
}

Bu da işe yarıyor. Ancak belirttiğiniz gibi, bununla birlikte tüm modelleri güncellemelisiniz, hizmetleri tercih ederim. AdddControllers ().
Nantharupan

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

Yukarıda da çalıştı. Ama aşağıdakileri tercih ederim

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

İlk önce özniteliği tüm modellere eklememiz gerektiğinden, döngüsel referansa sahip olabiliriz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.