Поделиться через


Связанные данные и сериализация

Так как EF Core автоматически исправляет свойства навигации, вы можете завершить циклы в графе объектов. Например, загрузка блога и связанных записей приведет к созданию объекта блога, который ссылается на коллекцию записей. Каждая из этих записей будет ссылкой на блог.

Некоторые платформы сериализации не допускают такие циклы. Например Json.NET вызовет следующее исключение при обнаружении цикла.

Newtonsoft.Json.JsonSerializationException: самоссылающийся цикл обнаружен для свойства "Blog" с типом MyApplication.Models.Blog.

System.Text.Json создает аналогичное исключение, если найден цикл.

System.Text.Json.JsonException: обнаружен возможный цикл объекта. Это может быть связано с циклом или если глубина объекта превышает максимальную допустимую глубину 32. Рекомендуется использовать ReferenceHandler.Preserve в JsonSerializerOptions для поддержки циклов.

Если вы используете Json.NET в ASP.NET Core, можно настроить Json.NET, чтобы игнорировать циклы, которые он находит в графе объектов. Настройка осуществляется с помощью метода ConfigureServices(...) в Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

    ...
}

Если вы используете System.Text.Json, его можно настроить следующим образом.

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
        });

    ...
}

Другой вариант — игнорировать свойства навигации, вызывающие цикл сериализации JSON. Если вы используете Json.NET, вы можете украсить одно из свойств навигации атрибутом [JsonIgnore] , которое предписывает Json.NET не проходить по такому свойству навигации при сериализации. Для System.Text.Json можно использовать [JsonIgnore] атрибут в System.Text.Json.Serialization пространстве имен для достижения того же эффекта.