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


System.Text.Json проверяет наличие конфликтов имен свойств

В определенных контекстах, таких как полиморфизм и сохранение ссылок, System.Text.Json резервирует определенные имена свойств (например, $type, $idи $ref) для создания метаданных. Некоторые имена свойств, такие как TypeDiscriminatorPropertyName, можно настроить с именами, заданными пользователем. Ранее сериализатор не выполнял проверку того, конфликтуют ли эти имена свойств с определяемыми пользователем контрактами, что может привести к повторяющимся свойствам и создать JSON, который был неоднозначным или не удалось выполнить круговую поездку. Начиная с .NET 10, System.Text.Json позволяет проверять такие конфигурации и обеспечивает раннее предупреждение для пользователей.

Представленная версия

.NET 10

Предыдущее поведение

Ранее следующий код создал недопустимый объект JSON с повторяющимися Type свойствами и не смог десериализировать с помощью JsonException:

using System.Text.Json;
using System.Text.Json.Serialization;

string json = JsonSerializer.Serialize<Animal>(new Dog());
Console.WriteLine(json); // {"Type":"dog","Type":"Dog"}
JsonSerializer.Deserialize<Animal>(json); // JsonException: Deserialized object contains a duplicate 'Type' metadata property.

[JsonPolymorphic(TypeDiscriminatorPropertyName = "Type")]
[JsonDerivedType(typeof(Dog), "dog")]
public abstract class Animal
{
    public abstract string Type { get; }
}

public class Dog : Animal
{
    public override string Type => "Dog";
}

Новое поведение

Начиная с .NET 10 любая попытка сериализации того же типа приводит к ошибке ранней проверки:

InvalidOperationException: тип "Собака" содержит свойство "Type", которое конфликтует с существующим именем свойства метаданных. Попробуйте переименовать его или игнорировать с помощью JsonIgnoreAttribute.

Эта ошибка проверки возникает при первом создании сериализатора или при первой попытке сериализации, обеспечивая раннее обнаружение недопустимых контрактов сериализации.

Тип разрушающего изменения

Это изменение поведения.

Причина изменения

Это изменение обеспечивает раннее предотвращение недопустимых контрактов сериализации. Проверяя имена свойств заранее, сериализатор предотвращает сценарии, в которых будут выдаваться повторяющиеся свойства, что приведет к созданию недопустимого JSON, который не может быть корректно преобразован туда и обратно. Это помогает разработчикам выявлять и устранять проблемы конфигурации во время разработки, а не обнаруживать их во время десериализации.

Дополнительные сведения можно найти здесь

Избегайте использования имен свойств, конфликтующих со свойствами метаданных, зависящими от System.Text.Json (например$type, и $id$ref). Если обязательно необходимо сохранить такое свойство в классе, примените JsonIgnoreAttribute аннотацию на конфликтующее свойство.

Затронутые API