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
- De manera predeterminada, se serializan todas las propiedades públicas. Puede especificar propiedades para omitir. También puede incluir miembros privados.
- El codificador predeterminado escapa a caracteres que no son ASCII, caracteres que distinguen HTML en el intervalo ASCII y caracteres que deben escaparse según la especificación de JSON RFC 8259.
- De forma predeterminada, JSON se minimiza. Puede imprimir correctamente el JSON.
- De forma predeterminada, el uso de mayúsculas y minúsculas en los nombres JSON coincide con el de los nombres de .NET. Puede personalizar el uso de mayúsculas y minúsculas e nombres JSON.
- De manera predeterminada, se detectan las referencias circulares y se inician las excepciones. Puede conservar las referencias y administrar las referencias circulares.
- De forma predeterminada, se omiten los campos. Puede incluir campos.
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:
Elementos primitivos de .NET que se asignan a elementos primitivos de JavaScript, tales como tipos numéricos, cadenas y valores booleanos.
Objetos CLR estándar (POCO) definidos por el usuario.
Matrices unidimensionales y escalonadas (
T[][]
).Colecciones y diccionarios de los siguientes espacios de nombres:
- System.Collections
- System.Collections.Generic
- System.Collections.Immutable
- System.Collections.Concurrent
- System.Collections.Specialized
- System.Collections.ObjectModel
Para obtener más información, consulte Tipos admitidos en System.Text.Json.
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. Puede personalizar la solicitud para usar campos de objeto que se adapten a sus requisitos.
En el texto siguiente se muestra un mensaje de ejemplo para Copilot Chat:
Generate code to use System.Text.Json to serialize an object to a JSON string.
The object contains the following fields: FirstName (string), Lastname (string), Age (int).
Provide example output.
GitHub Copilot funciona con IA, por lo que es posible que se produzcan sorpresas y errores. Para obtener más información, consulte Preguntas frecuentes de Copilot.
Obtenga más información sobre GitHub Copilot en Visual Studio y GitHub Copilot en VS Code.