это происходит потому, что ваши данные имеют ссылку l oop.
например
// this example creates a reference loop
var p = new Product()
{
ProductCategory = new ProductCategory()
{ products = new List<Product>() }
};
p.ProductCategory.products.Add(p); // <- this create the loop
var x = JsonSerializer.Serialize(p); // A possible object cycle was detected ...
Вы не можете обработать эталонную ситуацию l oop в новой System.Text.Json
пока (netcore 3.1.1), если вы полностью не игнорируете ссылку, и это не всегда хорошая идея. (используя атрибут [JsonIgnore]
)
, но у вас есть два варианта, чтобы это исправить.
вы можете использовать Newtonsoft.Json
в вашем проекте вместо System.Text.Json
(я связал для вас статью)
Загрузите System.Text.Json
версию пакета предварительного просмотра 5.0.0-alpha.1.20071.1
из галереи dotnet5 (через клиент NuGet в Visual Studio):
вариант 1, использование:
services.AddMvc()
.AddNewtonsoftJson(
options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
// if you not using .AddMvc use these methods instead
//services.AddControllers().AddNewtonsoftJson(...);
//services.AddControllersWithViews().AddNewtonsoftJson(...);
//services.AddRazorPages().AddNewtonsoftJson(...);
2 использование:
// for manual serializer
var options = new JsonSerializerOptions
{
ReferenceHandling = ReferenceHandling.Preserve
};
string json = JsonSerializer.Serialize(objectWithLoops, options);
// -----------------------------------------
// for asp.net core 3.1 (globaly)
services.AddMvc()
.AddJsonOptions(o => {
o.JsonSerializerOptions
.ReferenceHandling = ReferenceHandling.Preserve
});
эти сериализаторы имеют функцию ReferenceLoopHandling
.
но если вы решили просто игнорировать одну ссылку, используйте [JsonIgnore]
для одного из этих свойств. но это приводит к нулевому результату в вашем ответе API для этого поля, даже если у вас нет ссылки l oop.
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string ProductText { get; set; }
public int ProductCategoryId { get; set; }
// [JsonIgnore] HERE or
public virtual ProductCategory ProductCategory { get; set; }
}
public class ProductCategory
{
public int Id { get; set; }
// [JsonIgnore] or HERE
public ICollection<Product> products {get;set;}
}