Lenguaje

Cómo pasar por alto las propiedades con System.Text.Json

Al serializar objetos de C# en notación de objetos JavaScript (JSON), de forma predeterminada, se serializan todas las propiedades públicas. Si no quiere que algunos de ellos aparezcan en el JSON resultante, tiene varias opciones. En este artículo, aprenderá a omitir las propiedades en función de varios criterios:

Omitir propiedades individuales

Para pasar por alto las propiedades individuales, use el atributo [JsonIgnore].

En el ejemplo siguiente se muestra un tipo que se va a serializar. También muestra la salida JSON:

public class WeatherForecastWithIgnoreAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    [JsonIgnore]
    public string? Summary { get; set; }
}
Public Class WeatherForecastWithIgnoreAttribute
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer

    <JsonIgnore>
    Public Property Summary As String

End Class
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
}

Puede especificar la exclusión condicional estableciendo la propiedad del atributo Condition]. La JsonIgnoreCondition enumeración proporciona las siguientes opciones:

  • Always - La propiedad siempre se ignora. Si no se especifica Condition, se asume esta opción.
  • Never - La propiedad siempre se serializa y deserializa, independientemente de la configuración global DefaultIgnoreCondition, IgnoreReadOnlyProperties y IgnoreReadOnlyFields.
  • WhenWritingDefault - la propiedad se omite en la serialización si es un tipo de referencia null, un tipo de valor que admite nulos null, o un tipo de valor default.
  • WhenWritingNull: la propiedad se omite en la serialización si es un tipo de referencia null o un tipo de valor null que acepta valores nulos.

En el ejemplo siguiente se muestra el uso de la propiedad del atributo Condition

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

namespace JsonIgnoreAttributeExample
{
    public class Forecast
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
        public DateTime Date { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
        public int TemperatureC { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        public string? Summary { get; set; }
    };

    public class Program
    {
        public static void Run()
        {
            Forecast forecast = new()
            {
                Date = default,
                Summary = null,
                TemperatureC = default
            };

            JsonSerializerOptions options = new()
            {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
            };

            string forecastJson =
                JsonSerializer.Serialize<Forecast>(forecast,options);

            Console.WriteLine(forecastJson);
        }
    }
}

// Produces output like the following example:
//
//{"TemperatureC":0}
Imports System.Text.Json
Imports System.Text.Json.Serialization

Namespace JsonIgnoreAttributeExample

    Public Class Forecast

        <JsonIgnore(Condition:=JsonIgnoreCondition.WhenWritingDefault)>
        Public Property [Date] As Date

        <JsonIgnore(Condition:=JsonIgnoreCondition.Never)>
        Public Property TemperatureC As Integer

        <JsonIgnore(Condition:=JsonIgnoreCondition.WhenWritingNull)>
        Public Property Summary As String

    End Class

    Public NotInheritable Class Program

        Public Shared Sub Main()
            Dim forecast1 As New Forecast() With {
                .[Date] = CType(Nothing, Date),
                .Summary = Nothing,
                .TemperatureC = CType(Nothing, Integer)
                }

            Dim options As New JsonSerializerOptions() With {
                .DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
                }

            Dim forecastJson As String = JsonSerializer.Serialize(forecast1, options)

            Console.WriteLine(forecastJson)
        End Sub

    End Class

End Namespace

' Produces output like the following example:
'
'{"TemperatureC":0}

Omitir las propiedades en función de una condición de nivel de tipo

A partir de .NET 11, aplique [JsonIgnore(Condition = ...)] a una clase, estructura o interfaz para establecer la condición de omisión predeterminada para sus propiedades y campos:

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public class Forecast
{
    public string? Summary { get; set; }
}
<JsonIgnore(Condition:=JsonIgnoreCondition.WhenWritingNull)>
Public Class Forecast
    Public Property Summary As String
End Class

El serializador aplica la configuración de omisión en este orden, de mayor a menor precedencia:

En el nivel de tipo, Always no es válido. La serialización basada en reflexión genera un InvalidOperationException, y la generación de código fuente notifica SYSLIB1226. Dado que Always es la condición predeterminada, especifique Condition cuándo se aplica [JsonIgnore] a un tipo.

Una condición WhenWritingNull a nivel de tipo no ignora los miembros de tipo de valor no anulable. La condición de nivel de tipo todavía invalida el global DefaultIgnoreCondition, por lo que esos miembros permanecen en el JSON incluso cuando la condición global es WhenWritingDefault.

Omitir todas las propiedades de solo lectura

Una propiedad es de solo lectura si tiene un método de acceso público (getter), pero no un método de asignación público (setter). Para omitir todas las propiedades de solo lectura al serializar, establezca JsonSerializerOptions.IgnoreReadOnlyProperties en true, como se muestra en el ejemplo siguiente:

var options = new JsonSerializerOptions
{
    IgnoreReadOnlyProperties = true,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .IgnoreReadOnlyProperties = True,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, options)

En el ejemplo siguiente se muestra un tipo que se va a serializar. También muestra la salida JSON:

public class WeatherForecastWithROProperty
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    public int WindSpeedReadOnly { get; private set; } = 35;
}
Public Class WeatherForecastWithROProperty
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String
    Private _windSpeedReadOnly As Integer

    Public Property WindSpeedReadOnly As Integer
        Get
            Return _windSpeedReadOnly
        End Get
        Private Set(Value As Integer)
            _windSpeedReadOnly = Value
        End Set
    End Property

End Class
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
}

Esta opción solo se aplica a las propiedades. Para omitir los campos de solo lectura al serializar campos, use la JsonSerializerOptions.IgnoreReadOnlyFields configuración global.

Nota:

Las propiedades de tipo de colección de solo lectura se siguen serializando incluso si JsonSerializerOptions.IgnoreReadOnlyProperties se establece en true.

Omitir todas las propiedades con valor nulo

Para omitir todas las propiedades con valor nulo, establezca la propiedad DefaultIgnoreCondition en WhenWritingNull, como se muestra en el siguiente ejemplo:

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

namespace IgnoreNullOnSerialize
{
    public class Forecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
    };

    public class Program
    {
        public static void Run()
        {
            Forecast forecast = new()
            {
                Date = DateTime.Now,
                Summary = null,
                TemperatureC = default
            };

            JsonSerializerOptions options = new()
            {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
            };

            string forecastJson =
                JsonSerializer.Serialize<Forecast>(forecast, options);
            
            Console.WriteLine(forecastJson);
        }
    }
}

// Produces output like the following example:
//
//{"Date":"2020-10-30T10:11:40.2359135-07:00","TemperatureC":0}
Imports System.Text.Json

Namespace IgnoreNullOnSerialize

    Public Class Forecast
        Public Property [Date] As Date
        Public Property TemperatureC As Integer
        Public Property Summary As String
    End Class

    Public NotInheritable Class Program

        Public Shared Sub Main()
            Dim forecast1 As New Forecast() With
            {
            .[Date] = Date.Now,
            .Summary = Nothing,
            .TemperatureC = CType(Nothing, Integer)
            }

            Dim options As New JsonSerializerOptions

            Dim forecastJson As String = JsonSerializer.Serialize(forecast1, options)

            Console.WriteLine(forecastJson)
        End Sub

    End Class

End Namespace

' Produces output like the following example:
'
'{"Date":"2020-10-30T10:11:40.2359135-07:00","TemperatureC":0}

Omitir todas las propiedades de valor predeterminado

Para evitar la serialización de valores predeterminados en las propiedades de tipos de valor, establezca la propiedad DefaultIgnoreCondition en WhenWritingDefault, como se muestra en el ejemplo siguiente:

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

namespace IgnoreValueDefaultOnSerialize
{
    public class Forecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
    };

    public class Program
    {
        public static void Run()
        {
            Forecast forecast = new()
            {
                Date = DateTime.Now,
                Summary = null,
                TemperatureC = default
            };

            JsonSerializerOptions options = new()
            {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
            };

            string forecastJson =
                JsonSerializer.Serialize<Forecast>(forecast, options);

            Console.WriteLine(forecastJson);
        }
    }
}

// Produces output like the following example:
//
//{ "Date":"2020-10-21T15:40:06.8920138-07:00"}
Imports System.Text.Json
Imports System.Text.Json.Serialization

Namespace IgnoreValueDefaultOnSerialize

    Public Class Forecast
        Public Property [Date] As Date
        Public Property TemperatureC As Integer
        Public Property Summary As String
    End Class

    Public NotInheritable Class Program

        Public Shared Sub Main()
            Dim forecast1 As New Forecast() With
            {.[Date] = Date.Now,
              .Summary = Nothing,
              .TemperatureC = CType(Nothing, Integer)
            }

            Dim options As New JsonSerializerOptions() With {
                .DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
            }

            Dim forecastJson As String = JsonSerializer.Serialize(forecast1, options)

            Console.WriteLine(forecastJson)
        End Sub

    End Class

End Namespace

' Produces output like the following example:
'
'{ "Date":"2020-10-21T15:40:06.8920138-07:00"}

La configuración WhenWritingDefault también impide la serialización de las propiedades de tipo de referencia de valor nulo y de las propiedades de tipo de valor que admiten valores nulos.

Consulte también