Come scrivere oggetti .NET come JSON (serializzare)
Questo articolo illustra come usare lo spazio dei nomi System.Text.Json per serializzare in JavaScript Object Notation (JSON). Se si sta eseguendo la conversione di codice esistente da Newtonsoft.Json
, vedere Come eseguire la migrazione a System.Text.Json
.
Per scrivere JSON in una stringa o in un file, chiamare il metodo JsonSerializer.Serialize.
L'esempio seguente crea JSON come stringa:
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
L'output JSON viene minimizzato (spazi vuoti, rientro e caratteri di nuova riga vengono rimossi) per impostazione predefinita.
L'esempio seguente usa il codice sincrono per creare un file 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)
L'esempio seguente usa il codice asincrono per creare un file 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)
Negli esempi precedenti viene utilizzata l'inferenza del tipo per il tipo serializzato. Un overload di Serialize()
accetta un parametro di tipo generico:
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)
Comportamento della serializzazione
- Per impostazione predefinita, le proprietà pubblici vengono serializzati. È possibile specificare le proprietà da ignorare. È anche possibile includere membri privati.
- Il codificatore predefinito esegue l'escape di caratteri non ASCII, caratteri con distinzione HTML all'interno dell'intervallo ASCII e caratteri di escape in base alla specifica JSON RFC 8259.
- JSON viene minimizzato per impostazione predefinita. È possibile stampare il codice JSON.
- La combinazione di maiuscole e minuscole di nomi JSON corrisponde ai nomi .NET per impostazione predefinita. È possibile personalizzare la combinazione di maiuscole e minuscole dei nomi JSON.
- Per impostazione predefinita, vengono rilevati riferimenti circolari e vengono generate eccezioni. È possibile mantenere i riferimenti e gestire riferimenti circolari.
- Per impostazione predefinita, i campi vengono ignorati. È possibile includere campi.
Quando si usa System.Text.Json indirettamente in un'app ASP.NET Core, alcuni comportamenti predefiniti sono diversi. Per altre informazioni, vedere Riutilizzare le istanze JsonSerializerOptions.
I tipi supportati includono:
Primitive .NET mappate a JavaScript primitive, ad esempio tipi numerici, stringhe e booleani.
Oggetti CLR (POCO) definiti dall'utente.
Matrici unidimensionali e matrice di matrici (
T[][]
).Raccolte e dizionari dagli spazi dei nomi seguenti:
- System.Collections
- System.Collections.Generic
- System.Collections.Immutable
- System.Collections.Concurrent
- System.Collections.Specialized
- System.Collections.ObjectModel
Per ulteriori informazioni, vedere Tipi di raccolta supportati inSystem.Text.Json.
È possibile implementare convertitori personalizzati per gestire tipi aggiuntivi o per fornire funzionalità non supportate dai convertitori predefiniti.
Di seguito è riportato un esempio che mostra come viene serializzata una classe che contiene le proprietà della raccolta e un tipo definito dall'utente:
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"
' ]
' }
Serializzare in UTF-8
Serializzare in una matrice di byte UTF-8 più veloce del 5-10% rispetto all'uso dei metodi basati su stringa. Questo perché i byte (come UTF-8) non devono essere convertiti in stringhe (UTF-16).
Per serializzare in una matrice di byte UTF-8, chiamare il metodo 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)
È disponibile anche un overload Serialize che accetta un Utf8JsonWriter.
Serializzare in JSON formattato
Per stampare in modo corretto l'output JSON, impostare JsonSerializerOptions.WriteIndented su 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)
Suggerimento
Se si usa JsonSerializerOptions
ripetutamente con le stesse opzioni, non creare una nuova istanza JsonSerializerOptions
ogni volta che viene usata. Riutilizzare la stessa istanza per ogni chiamata. Per altre informazioni, vedere Riutilizzare le istanze JsonSerializerOptions.