Udostępnij przez


Jak odczytać JSON jako obiekty platformy .NET (deserializować)

W tym artykule pokazano, jak używać System.Text.Json przestrzeni nazw do deserializacji z pliku JavaScript Object Notation (JSON). Jeśli przenosisz istniejący kod z Newtonsoft.Jsonprogramu , zobacz Jak przeprowadzić migrację do System.Text.Jsonprogramu .

Typowym sposobem deserializacji danych JSON jest posiadanie (lub utworzenie) klasy .NET z właściwościami i polami reprezentującymi co najmniej jedną właściwości JSON. Następnie, aby deserializować z ciągu lub pliku, wywołaj metodę JsonSerializer.Deserialize . W przypadku przeciążeń ogólnych parametr typu ogólnego jest klasą .NET. W przypadku przeciążeń innych niż ogólne należy przekazać typ klasy jako parametr metody. Można deserializować synchronicznie lub asynchronicznie.

Wszystkie właściwości JSON, które nie są reprezentowane w klasie, są domyślnie ignorowane. Ponadto, jeśli jakiekolwiek właściwości typu są wymagane , ale nie są obecne w ładunku JSON, deserializacja zakończy się niepowodzeniem.

Przykłady

W poniższym przykładzie pokazano, jak deserializować ciąg JSON zawierający kolekcje i zagnieżdżone obiekty:

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}");

            if (weatherForecast?.DatesAvailable != null)
            {
                foreach (DateTimeOffset dateTimeOffset in weatherForecast.DatesAvailable)
                {
                    Console.WriteLine($"DateAvailable: {dateTimeOffset}");
                }
            }

            if (weatherForecast?.TemperatureRanges != null)
            {
                foreach (KeyValuePair<string, HighLowTemps> temperatureRange in weatherForecast.TemperatureRanges)
                {
                    Console.WriteLine($"TemperatureRange: {temperatureRange.Key} is {temperatureRange.Value.Low} to {temperatureRange.Value.High}");
                }
            }

            if (weatherForecast?.SummaryWords != null)
            {
                foreach (string summaryWord in weatherForecast.SummaryWords)
                {
                    Console.WriteLine($"SummaryWord: {summaryWord}");
                }
            }
        }
    }
}

/* Output:
 * 
 * Date: 8/1/2019 12:00:00 AM -07:00
 * TemperatureCelsius: 25
 * Summary: Hot
 * DateAvailable: 8/1/2019 12:00:00 AM -07:00
 * DateAvailable: 8/2/2019 12:00:00 AM -07:00
 * TemperatureRange: Cold is -10 to 20
 * TemperatureRange: Hot is 20 to 60
 * SummaryWord: Cool
 * SummaryWord: Windy
 * SummaryWord: Humid
 * */
Imports System.Text.Json

Namespace DeserializeExtra

    Public Class WeatherForecast
        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

    Public NotInheritable Class Program

        Public Shared Sub Run()
            Dim jsonString As String =
                "{
                  ""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""
                  ]
                }"

            Dim weatherForecast As WeatherForecast =
                JsonSerializer.Deserialize(Of WeatherForecast)(jsonString)

            Console.WriteLine($"Date: {weatherForecast?.Date}")
            Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}")
            Console.WriteLine($"Summary: {weatherForecast?.Summary}")

            If weatherForecast?.DatesAvailable IsNot Nothing Then
                For Each dateTimeOffset As DateTimeOffset In weatherForecast.DatesAvailable
                    Console.WriteLine($"DateAvailable: {dateTimeOffset}")
                Next
            End If

            If weatherForecast?.TemperatureRanges IsNot Nothing Then
                For Each temperatureRange As KeyValuePair(Of String, HighLowTemps) In weatherForecast.TemperatureRanges
                    Console.WriteLine($"TemperatureRange: {temperatureRange.Key} is {temperatureRange.Value.Low} to {temperatureRange.Value.High}")
                Next
            End If

            If weatherForecast?.SummaryWords IsNot Nothing Then
                For Each summaryWord As String In weatherForecast.SummaryWords
                    Console.WriteLine($"SummaryWord: {summaryWord}")
                Next
            End If
        End Sub

    End Class

End Namespace

' Output:
'
'Date: 8/1/2019 12:00:00 AM -07:00
'TemperatureCelsius: 25
'Summary: Hot
'DateAvailable: 8/1/2019 12:00:00 AM -07:00
'DateAvailable: 8/2/2019 12:00:00 AM -07:00
'TemperatureRange: Cold is -10 to 20
'TemperatureRange: Hot is 20 to 60
'SummaryWord: Cool
'SummaryWord: Windy
'SummaryWord: Humid

Aby wykonać deserializacji z pliku przy użyciu kodu synchronicznego, odczytaj plik w ciągu, jak pokazano w poniższym przykładzie:

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)

Aby wykonać deserializowanie z pliku przy użyciu kodu asynchronicznego, wywołaj metodę 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)

Zachowanie deserializacji

Podczas deserializacji kodu JSON obowiązują następujące zachowania:

Jeśli używasz System.Text.Json pośrednio w aplikacji ASP.NET Core, niektóre zachowania domyślne są inne. Aby uzyskać więcej informacji, zobacz Ustawienia domyślne sieci Web dla JsonSerializerOptions.

Możesz zaimplementować konwertery niestandardowe, aby zapewnić funkcjonalność, która nie jest obsługiwana przez wbudowane konwertery.

Deserializacja bez użycia klasy .NET

Jeśli masz JSON, który chcesz przeprowadzić deserializację i nie masz klasy, do której można go deserializować, masz inne opcje niż ręczne tworzenie potrzebnej klasy:

Deserializowanie z utF-8

Aby wykonać deserializację z UTF-8, wywołaj JsonSerializer.Deserialize przeciążenie, które przyjmuje ReadOnlySpan<byte> lub Utf8JsonReader, jak pokazano w poniższych przykładach. W przykładach przyjęto założenie, że kod JSON znajduje się w tablicy bajtów o nazwie 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

Używanie sztucznej inteligencji do deserializacji danych JSON

Za pomocą narzędzi sztucznej inteligencji, takich jak GitHub Copilot, można wygenerować kod, który używa System.Text.Json do deserializacji z formatu JSON. Można na przykład dostosować monit, aby zademonstrować deserializacji, gdy klasa docelowa definiuje właściwość, której brakuje w danych wejściowych JSON.

Poniższy tekst przedstawia przykładowy monit dotyczący czatu copilot:

Generate C# code to use System.Text.Json to deserialize a JSON string {"FirstName":"John","LastName":"Doe"} to an equivalent .NET object, where the class defines an Age property.
Show what happens when the JSON is missing a property defined in the class.
Provide example output.

Przed ich zastosowaniem przejrzyj sugestie Copilota.

Aby uzyskać więcej informacji na temat narzędzia GitHub Copilot, zobacz Często zadawane pytania dotyczące usługi GitHub.

Zobacz także