如何將 JSON 讀取為 .NET 物件 (還原序列化)
本文介紹如何使用 System.Text.Json 命名空間從 JavaScript Object Notation (JSON) 還原序列化。 如果要從 Newtonsoft.Json
移植現有的程式碼,請參閱如何移轉至 System.Text.Json
。
將 JSON 還原序列化的常見方式是擁有 (或建立) 具有屬性和欄位的 .NET 類別,這些代表一個或多個 JSON 屬性。 然後,若要將字串或檔案還原序列化,請呼叫 JsonSerializer.Deserialize 方法。 針對泛型多載,泛型型別參數是 .NET 類別。 針對非泛型多載,您會傳遞類別型別做為方法參數。 您可以同步或非同步還原序列化。
提示
您可以使用 AI 輔助來利用 GitHub Copilot 將 JSON 字串還原序列化。
根據預設,系統會忽略類別中未表示的任何 JSON 屬性。 此外,如果型別上的任何屬性是必要的,但不存在於 JSON 承載中,還原序列化將會失敗。
範例
下列範例示範如何將 JSON 字串還原序列化:
using System.Text.Json;
namespace DeserializeExtra
{
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()
{
string jsonString =
"""
{
"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"
]
}
""";
WeatherForecast? weatherForecast =
JsonSerializer.Deserialize<WeatherForecast>(jsonString);
Console.WriteLine($"Date: {weatherForecast?.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast?.Summary}");
}
}
}
// output:
//Date: 8/1/2019 12:00:00 AM -07:00
//TemperatureCelsius: 25
//Summary: Hot
weatherForecast = JsonSerializer.Deserialize(Of WeatherForecastWithPOCOs)(jsonString)
若要使用同步程式碼從檔案還原序列化,請將檔案讀入字串,如下列範例所示:
using System.Text.Json;
namespace DeserializeFromFile
{
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()
{
string fileName = "WeatherForecast.json";
string jsonString = File.ReadAllText(fileName);
WeatherForecast weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString)!;
Console.WriteLine($"Date: {weatherForecast.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast.Summary}");
}
}
}
// output:
//Date: 8/1/2019 12:00:00 AM -07:00
//TemperatureCelsius: 25
//Summary: Hot
jsonString = File.ReadAllText(fileName)
weatherForecast1 = JsonSerializer.Deserialize(Of WeatherForecast)(jsonString)
若要使用非同步程式碼將檔案還原序列化,請呼叫 DeserializeAsync 方法:
using System.Text.Json;
namespace DeserializeFromFileAsync
{
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()
{
string fileName = "WeatherForecast.json";
using FileStream openStream = File.OpenRead(fileName);
WeatherForecast? weatherForecast =
await JsonSerializer.DeserializeAsync<WeatherForecast>(openStream);
Console.WriteLine($"Date: {weatherForecast?.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast?.Summary}");
}
}
}
// output:
//Date: 8/1/2019 12:00:00 AM -07:00
//TemperatureCelsius: 25
//Summary: Hot
Dim openStream As FileStream = File.OpenRead(fileName)
weatherForecast1 = Await JsonSerializer.DeserializeAsync(Of WeatherForecast)(openStream)
還原序列化行為
還原序列化 JSON 時,下列行為適用:
- 根據預設,屬性名稱比對會區分大小寫。 您可以指定不區分大小寫。
- 序列化程式會忽略非公用建構函式。
- 支援還原序列化為不可變的物件或沒有公用
set
存取子的屬性,但預設不會啟用。 請參閱不可變的型別和記錄。 - 根據預設,支援列舉為數字。 您可以還原序列化字串列舉欄位。
- 根據預設,會忽略欄位。 您可以包含欄位。
- 根據預設,JSON 中的註解或後置逗號會擲回例外狀況。 您可以允許註解和後置逗號。
- 預設的最大深度為 64。
您在 ASP.NET Core 應用程式中間接使用 System.Text.Json 時,某些預設行為會有所不同。 如需詳細資訊,請參閱 JsonSerializerOptions 的 Web 預設值。
您可以實作自訂轉換器來提供內建轉換器不支援的功能。
不使用 .NET 類別還原序列化
如果您想要將 JSON 還原序列化,而且沒有要還原序列化的類別,則您會有手動建立所需類別以外的選項:
直接使用 Utf8JsonReader。
還原序列化為 JSON DOM (文件物件模型),並從 DOM 擷取所需內容。
DOM 可讓您瀏覽至 JSON 承載的子區段,並將單一值、自訂型別或陣列還原序列化。 如需 JsonNode DOM 相關資訊,請參閱還原序列化 JSON 承載的子區段。 如需 DOM 的資訊,請參閱JsonDocument如何搜尋子項目的 JsonDocument 和 JsonElement。
使用 Visual Studio 2022 自動產生您需要的類別:
- 複製還原序列化所需的 JSON。
- 建立類別檔案並刪除範本程式碼。
- 選擇 [編輯]> [選擇性貼上]> [將 JSON 貼上為類別]。
結果為可用在將目標還原序列化的類別。
從 UTF-8 將其還原序列化
如果要從 UTF-8 將其還原序列化,請呼叫採用 JsonSerializer.Deserialize 或 ReadOnlySpan<byte>
的 Utf8JsonReader
多載,如下列範例所示。 這些範例假設 JSON 位於名稱為 jsonUtf8Bytes 的位元組陣列中。
var readOnlySpan = new ReadOnlySpan<byte>(jsonUtf8Bytes);
WeatherForecast deserializedWeatherForecast =
JsonSerializer.Deserialize<WeatherForecast>(readOnlySpan)!;
Dim jsonString = Encoding.UTF8.GetString(jsonUtf8Bytes)
weatherForecast1 = JsonSerializer.Deserialize(Of WeatherForecast)(jsonString)
var utf8Reader = new Utf8JsonReader(jsonUtf8Bytes);
WeatherForecast deserializedWeatherForecast =
JsonSerializer.Deserialize<WeatherForecast>(ref utf8Reader)!;
' This code example doesn't apply to Visual Basic. For more information, go to the following URL:
' https://learn.microsoft.com/dotnet/standard/serialization/system-text-json-how-to#visual-basic-support
使用 GitHub Copilot 將 JSON 還原序列化
您可以在 IDE 中使用 GitHub Copilot 以產生使用 System.Text.Json
從 JSON 還原序列化的程式碼。 您可以自訂提示,以搭配符合您需求的屬性名稱和值使用 JSON 字串。
下列文字顯示 Copilot Chat 的範例提示:
Generate code to use System.Text.Json to deserialize a JSON string {"FirstName":"John","LastName":"Doe","Age":30} to an equivalent .NET object.
Map property names & values.
Provide example output.
GitHub Copilot 是由 AI 驅動的,因此可能會有意外和錯誤的情況發生。 如需詳細資訊,請參閱 Copilot 常見問題。
深入瞭解在 Visual Studio 中 GitHub Copilot 和 VS Code GitHub Copilot。