共用方式為


如何將 JSON 讀取為 .NET 物件 (還原序列化)

本文說明如何使用 System.Text.Json 命名空間,針對 JavaScript 物件標記法 (JSON) 序列化和還原序列化。 如果要從 Newtonsoft.Json 移植現有的程式碼,請參閱如何移轉至 System.Text.Json

將 JSON 還原序列化的常見方式是擁有 (或建立) 具有屬性和欄位的 .NET 類別,這些代表一個或多個 JSON 屬性。 然後,若要將字串或檔案還原序列化,請呼叫 JsonSerializer.Deserialize 方法。 針對泛型多載,泛型型別參數是 .NET 類別。 針對非泛型多載,您會傳遞類別型別做為方法參數。 您可以同步或非同步還原序列化。

根據預設,系統會忽略類別中未表示的任何 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 時,下列行為適用:

您在 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 將其還原序列化,請呼叫採用 ReadOnlySpan<byte>Utf8JsonReaderJsonSerializer.Deserialize 多載,如下列範例所示。 這些範例假設 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