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


Обязательные свойства

Вы можете пометить определенные свойства, чтобы означать, что они должны присутствовать в полезных данных JSON для успешной десериализации. Аналогичным образом можно задать параметр, чтобы указать, что все не необязательные параметры конструктора присутствуют в полезных данных JSON. Если один или несколько из этих обязательных свойств отсутствуют, JsonSerializer.Deserialize методы вызывают JsonExceptionисключение.

Для десериализации JSON можно пометить свойство или поле тремя способами:

Чтобы указать, что для десериализации JSON требуются все не необязательные параметры конструктора, задайте JsonSerializerOptions.RespectRequiredConstructorParameters параметр (или для создания источника, RespectRequiredConstructorParameters свойства).true Дополнительные сведения см. в разделе параметров конструктора, не необязательного.

С точки зрения сериализатора модификатор C# required и [JsonRequired] атрибут эквивалентны, и оба сопоставляются с одной и той же частью метаданных, то есть JsonPropertyInfo.IsRequired. В большинстве случаев вы просто используете встроенное ключевое слово C#. Однако в следующих случаях следует использовать JsonRequiredAttribute следующее:

  • Если вы используете язык программирования, отличный от C# или версию C#нижнего уровня.
  • Если требуется применить только требование к десериализации JSON.
  • При использовании System.Text.Json сериализации в режиме создания источника. В этом случае код не будет компилироваться, если используется required модификатор, так как создание источника происходит во время компиляции.

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

public static void RunIt()
{
    // The following line throws a JsonException at run time.
    Console.WriteLine(JsonSerializer.Deserialize<Person>("""{"Age": 42}"""));
}

public class Person
{
    public required string Name { get; set; }
    public int Age { get; set; }
}

В качестве альтернативы вы можете использовать JsonRequiredAttribute:

public static void RunIt()
{
    // The following line throws a JsonException at run time.
    Console.WriteLine(JsonSerializer.Deserialize<Person>("""{"Age": 42}"""));
}

public class Person
{
    [JsonRequired]
    public string Name { get; set; }
    public int Age { get; set; }
}

Кроме того, можно контролировать, требуется ли свойство с помощью модели контракта с помощью JsonPropertyInfo.IsRequired свойства:

public static void RunIt()
{
    var options = new JsonSerializerOptions
    {
        TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                static typeInfo =>
                {
                    if (typeInfo.Kind != JsonTypeInfoKind.Object)
                        return;

                    foreach (JsonPropertyInfo propertyInfo in typeInfo.Properties)
                    {
                        // Strip IsRequired constraint from every property.
                        propertyInfo.IsRequired = false;
                    }
                }
            }
        }
    };

    // Deserialization succeeds even though
    // the Name property isn't in the JSON payload.
    JsonSerializer.Deserialize<Person>("""{"Age": 42}""", options);
}

public class Person
{
    public required string Name { get; set; }
    public int Age { get; set; }
}

Параметры конструктора, не являющиеся необязательными

До .NET 9 десериализация на основе конструктора обрабатывала все параметры конструктора как необязательные, как показано в следующем примере:

var result = JsonSerializer.Deserialize<Person>("{}");
Console.WriteLine(result); // Person { Name = , Age = 0 }

record Person(string Name, int Age);

Начиная с .NET 9, флаг можно задать RespectRequiredConstructorParameters для обработки не необязательных параметров конструктора по мере необходимости.

public static void RunIt()
{
    JsonSerializerOptions options = new()
    {
        RespectRequiredConstructorParameters = true
    };
    string json = """{"Age": 42}""";

    // The following line throws a JsonException at run time.
    JsonSerializer.Deserialize<Person>(json, options);
}

record Person(string Name, int? Age = null);

Переключатели функции

Вы можете включить RespectRequiredConstructorParameters параметр глобально с помощью System.Text.Json.Serialization.RespectRequiredConstructorParametersDefault переключателя функций. Добавьте следующий элемент MSBuild в файл проекта (например, CSPROJ-файл ):

<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Text.Json.Serialization.RespectRequiredConstructorParametersDefault" Value="true" />
</ItemGroup>

RespectRequiredConstructorParametersDefault API был реализован как флаг согласия в .NET 9, чтобы избежать нарушения существующих приложений. Если вы пишете новое приложение, настоятельно рекомендуется включить этот флаг в коде.

См. также