Propiedades obligatorias

A partir de .NET 7 puede marcar ciertas propiedades para indicar que deben estar presentes en la carga de JSON para que la deserialización se realice correctamente. Si una o varias de estas propiedades necesarias no están presentes, los métodos JsonSerializer.Deserialize inician una excepción JsonException.

Hay tres maneras de marcar una propiedad o un campo según proceda para la deserialización JSON:

Desde la perspectiva del serializador, estas dos demarcaciones son equivalentes y ambas se asignan a la misma parte de los metadatos, JsonPropertyInfo.IsRequired. En la mayoría de los casos, simplemente usaría la palabra clave integrada de C#. Sin embargo, en los siguientes, debe usar JsonRequiredAttribute en su lugar:

  • Si usa un lenguaje de programación distinto de C# o una versión inferior de C#.
  • Si quiere que la obligación solo se aplique a la deserialización JSON.
  • Si usa la serialización System.Text.Json en modo de generación de origen. En este caso, el código no se compilará si usa el modificador required, ya que la generación de origen se produce en tiempo de compilación.

En el siguiente fragmento de código se muestra un ejemplo de una propiedad modificada con la palabra clave required. Esta propiedad debe estar presente en la carga de JSON para que la deserialización se realice correctamente.

using System.Text.Json;

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

Como alternativa, puede usar JsonRequiredAttribute:

using System.Text.Json;

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

También es posible controlar si se requiere una propiedad mediante el modelo de contrato con la propiedad JsonPropertyInfo.IsRequired:

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 now succeeds even though the Name property isn't in the JSON payload.
JsonSerializer.Deserialize<Person>("""{"Age": 42}""", options);