Escritura de objetos .NET como JSON (serializar)

En este artículo se muestra cómo usar el espacio de nombres System.Text.Json para serializar en notación de objetos JavaScript (JSON). Si va a portar el código existente de Newtonsoft.Json, consulte Procedimiento para migrar a System.Text.Json.

Sugerencia

Puede usar la asistencia de IA para serializar en JSON con GitHub Copilot.

Para escribir JSON en una cadena o un archivo, llame al método JsonSerializer.Serialize.

Ejemplos de serialización

En el ejemplo siguiente se crea un archivo JSON como cadena:

using System.Text.Json;

namespace SerializeBasic
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string jsonString = JsonSerializer.Serialize(weatherForecast);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
Dim jsonString As String

La salida JSON se reduce (se quitan los caracteres de espacio en blanco, sangría y nueva línea) de forma predeterminada.

En el ejemplo siguiente se usa código sincrónico para crear un archivo JSON:

using System.Text.Json;

namespace SerializeToFile
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string fileName = "WeatherForecast.json"; 
            string jsonString = JsonSerializer.Serialize(weatherForecast);
            File.WriteAllText(fileName, jsonString);

            Console.WriteLine(File.ReadAllText(fileName));
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
jsonString = JsonSerializer.Serialize(weatherForecast1)
File.WriteAllText(fileName, jsonString)

En el ejemplo siguiente se usa código asincrónico para crear un archivo JSON:

using System.Text.Json;

namespace SerializeToFileAsync
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static async Task Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string fileName = "WeatherForecast.json";
            await using FileStream createStream = File.Create(fileName);
            await JsonSerializer.SerializeAsync(createStream, weatherForecast);

            Console.WriteLine(File.ReadAllText(fileName));
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
Dim createStream As FileStream = File.Create(fileName)
Await JsonSerializer.SerializeAsync(createStream, weatherForecast1)

En los ejemplos anteriores se usa la inferencia de tipos para el tipo que se está serializando. Una sobrecarga de Serialize() toma un parámetro de tipo genérico:

using System.Text.Json;

namespace SerializeWithGenericParameter
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string jsonString = JsonSerializer.Serialize<WeatherForecast>(weatherForecast);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
jsonString = JsonSerializer.Serialize(Of WeatherForecastWithPOCOs)(weatherForecast)

También puede usar GitHub Copilot para generar código de serialización automáticamente. Para obtener instrucciones, consulte la sección Uso de GitHub Copilot en este artículo.

Comportamiento de serialización

Cuando se usa System.Text.Json indirectamente en una aplicación ASP.NET Core, algunos comportamientos predeterminados son diferentes. Para obtener más información, vea Valores predeterminados web para JsonSerializerOptions.

Los tipos no admitidos incluyen:

Puede implementar convertidores personalizados para controlar tipos adicionales o proporcionar funcionalidad que no admiten los convertidores integrados.

Este es un ejemplo que muestra cómo se serializa una clase que contiene propiedades de recopilación y un tipo definido por el usuario:

using System.Text.Json;

namespace SerializeExtra
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
        public string? SummaryField;
        public IList<DateTimeOffset>? DatesAvailable { get; set; }
        public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
        public string[]? SummaryWords { get; set; }
    }

    public class HighLowTemps
    {
        public int High { get; set; }
        public int Low { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot",
                SummaryField = "Hot",
                DatesAvailable = new List<DateTimeOffset>() 
                    { DateTime.Parse("2019-08-01"), DateTime.Parse("2019-08-02") },
                TemperatureRanges = new Dictionary<string, HighLowTemps>
                    {
                        ["Cold"] = new HighLowTemps { High = 20, Low = -10 },
                        ["Hot"] = new HighLowTemps { High = 60 , Low = 20 }
                    },
                SummaryWords = new[] { "Cool", "Windy", "Humid" }
            };

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00-07:00",
//  "TemperatureCelsius": 25,
//  "Summary": "Hot",
//  "DatesAvailable": [
//    "2019-08-01T00:00:00-07:00",
//    "2019-08-02T00:00:00-07:00"
//  ],
//  "TemperatureRanges": {
//    "Cold": {
//      "High": 20,
//      "Low": -10
//    },
//    "Hot": {
//    "High": 60,
//      "Low": 20
//    }
//  },
//  "SummaryWords": [
//    "Cool",
//    "Windy",
//    "Humid"
//  ]
//}
Public Class WeatherForecastWithPOCOs
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String
    Public SummaryField As String
    Public Property DatesAvailable As IList(Of DateTimeOffset)
    Public Property TemperatureRanges As Dictionary(Of String, HighLowTemps)
    Public Property SummaryWords As String()
End Class

Public Class HighLowTemps
    Public Property High As Integer
    Public Property Low As Integer
End Class

' serialization output formatted (pretty-printed with whitespace and indentation):
' {
'   "Date": "2019-08-01T00:00:00-07:00",
'   "TemperatureCelsius": 25,
'   "Summary": "Hot",
'   "DatesAvailable": [
'     "2019-08-01T00:00:00-07:00",
'     "2019-08-02T00:00:00-07:00"
'   ],
'   "TemperatureRanges": {
'     "Cold": {
'       "High": 20,
'       "Low": -10
'     },
'     "Hot": {
'       "High": 60,
'       "Low": 20
'     }
'   },
'   "SummaryWords": [
'     "Cool",
'     "Windy",
'     "Humid"
'   ]
' }

Serialización a UTF-8

Es del 5 al 10 % más rápido serializar en una matriz de bytes UTF-8 que usar los métodos basados en cadenas. Esto se debe a que los bytes (como UTF-8) no necesitan convertirse en cadenas (UTF-16).

Para serializar en una matriz de bytes de UTF-8, llame al método JsonSerializer.SerializeToUtf8Bytes:

byte[] jsonUtf8Bytes =JsonSerializer.SerializeToUtf8Bytes(weatherForecast);
Dim jsonUtf8Bytes As Byte()
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .WriteIndented = True
}
jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(weatherForecast1, options)

También está disponible una sobrecarga Serialize que toma un valor Utf8JsonWriter.

Serialización a JSON con formato

Para imprimir correctamente la salida JSON, establezca JsonSerializerOptions.WriteIndented en true:

using System.Text.Json;

namespace SerializeWriteIndented
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00-07:00",
//  "TemperatureCelsius": 25,
//  "Summary": "Hot"
//}
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, options)

A partir de .NET 9, también se puede personalizar el carácter y el tamaño de la sangría mediante IndentCharacter y IndentSize.

Sugerencia

Si usa JsonSerializerOptions repetidas veces con las mismas opciones, no cree una instancia de JsonSerializerOptions cada vez que lo use. Reutilice la misma instancia para cada llamada. Para obtener más información, vea Reutilización de instancias de JsonSerializerOptions.

Uso de GitHub Copilot para serializar en JSON

Puede usar GitHub Copilot en el IDE para generar código que use System.Text.Json para serializar en JSON.

Si usa Visual Studio 2022, versión 17.8 o posterior, puede probar GitHub Copilot controlado por IA en Visual Studio para generar código que use System.Text.Json para serializar en JSON. Envíe su pregunta como solicitud en la ventana de chat de Copilot, como en el ejemplo siguiente. También puede enviar mensajes mediante el chat en línea en la propia ventana del editor.

Nota:

GitHub Copilot funciona con IA, por lo que es posible que se produzcan sorpresas y errores. Asegúrese de comprobar cualquier código o sugerencia generado. Para obtener más información sobre el uso general de GitHub Copilot, impacto en el producto, supervisión humana y privacidad, consulte Preguntas más frecuentes sobre GitHub Copilot.

En el texto siguiente se muestra un mensaje de ejemplo para Copilot Chat:

Genere código para usar System.Text.Json para serializar un objeto en una cadena JSON. El objeto contiene los siguientes campos: FirstName (string), Lastname (string), Age (int). Proporcione una salida de ejemplo.

Puede personalizar la solicitud para usar campos de objeto que se adapten a sus requisitos.

Puede usar características de chat, como comandos de barra diagonal, referencias a archivos, métodos, clases y subprocesos, para establecer la intención y obtener mejores respuestas con contexto con ámbito. Para una clase existente en un proyecto abierto en el IDE, puede solicitar GitHub Copilot con /generate code to serialize #Classname in #Filename to JSON

En la salida siguiente se muestra un ejemplo de respuesta de Copilot Chat:

Sure! Below is an example of how to use System.Text.Json to serialize an object with the specified fields to a JSON string in C#:

using System;
using System.Text.Json;

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main()
    {
        var person = new Person
        {
            FirstName = "John",
            LastName = "Doe",
            Age = 30
        };

        string jsonString = JsonSerializer.Serialize(person);
        Console.WriteLine(jsonString);
    }
}

**Example Output**
{"FirstName":"John","LastName":"Doe","Age":30}

This code defines a `Person` class, creates an instance of it, and then serializes it to a JSON string using `JsonSerializer.Serialize`. The resulting JSON string is then printed to the console.

Cuando Copilot devuelve un bloque de código, la respuesta incluye opciones para copiar el código, insertar el código en un nuevo archivo u obtener una vista previa de la salida del código.

Nota:

Los resultados pueden ser diferentes de lo que se muestra en las respuestas de ejemplo. Los modelos de IA no son deterministas, lo que significa que pueden devolver respuestas diferentes cuando se le haga la misma pregunta. Esto puede deberse al aprendizaje y la adaptación adicionales a lo largo del tiempo, la variación del lenguaje, los cambios en el contexto, como el historial de chat, etc.

Captura de pantalla animada que muestra el uso de GitHub Copilot Chat en Visual Studio para serializar un objeto en una cadena JSON.

Para más información, vea: