Как сериализировать и десериализировать (маршалирование и демаршалирование) JSON в .NET

Эта статья содержит сведения об использовании пространства имен System.Text.Json для сериализации и десериализации в нотации объектов JavaScript (JSON) и из нее. Если вы переносите существующий код из Newtonsoft.Json, ознакомьтесь со статьей Переход с Newtonsoft.Json на System.Text.JsonSystem.Text.Json.

Примеры кода

Примеры кода в этой статье:

  • Используйте библиотеку напрямую, а не через платформу, например ASP.NET Core.

  • JsonSerializer Используйте класс с пользовательскими типами для сериализации из и десериализации в .

    Сведения о чтении и записи данных JSON без использования JsonSerializerсм. в статье Использование JSON DOM, Utf8JsonReader и Utf8JsonWriter.

  • WriteIndented Используйте параметр для форматирования JSON для удобства чтения, если это удобно.

    Для использования в рабочей среде обычно принимается значение false по умолчанию для этого параметра, так как добавление ненужных пробелов может негативно повлиять на производительность и использование пропускной способности.

  • Обратитесь к следующему классу и его вариантам:

    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }
    
    Public Class WeatherForecast
        Public Property [Date] As DateTimeOffset
        Public Property TemperatureCelsius As Integer
        Public Property Summary As String
    End Class
    

Пространства имен

Пространство имен System.Text.Json содержит все точки входа и основные типы. Пространство имен System.Text.Json.Serialization содержит атрибуты и интерфейсы API для сложных сценариев и настройки, характерной для сериализации и десериализации. В примерах кода, приведенных в этой статье, для одного или обоих пространств имен необходимо добавить директивы using:

using System.Text.Json;
using System.Text.Json.Serialization;
Imports System.Text.Json
Imports System.Text.Json.Serialization

Важно!

Как записать объекты .NET в формате JSON (сериализация)

Чтобы записать JSON в строку или в файл, вызовите метод JsonSerializer.Serialize.

В следующем примере показано создание JSON в виде строки:

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

Выходные данные JSON уменьшены (пробелы, отступы и символы новой строки удаляются) по умолчанию.

В примере ниже для создания 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)

В следующем примере для создания 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";
            using FileStream createStream = File.Create(fileName);
            await JsonSerializer.SerializeAsync(createStream, weatherForecast);
            await createStream.DisposeAsync();

            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)

В предыдущих примерах для сериализуемого типа используется определение типа. Перегрузка Serialize() принимает параметр универсального типа:

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)

Пример сериализации

Ниже приведен пример сериализации класса, содержащего свойства коллекции и определяемый пользователем тип:

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"
'   ]
' }

Сериализация в UTF-8

Сериализация в массив байтов UTF-8 выполняется примерно на 5–10 % быстрее, чем при использовании строковых методов. Разница заключается в том, что байты (например, UTF-8) не нужно преобразовывать в строки (UTF-16).

Чтобы сериализоваться в массив байтов UTF-8, вызовите 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)

Также доступна перегрузка Serialize, которая принимает Utf8JsonWriter.

Поведение сериализации

При косвенном использовании System.Text.Json в приложении ASP.NET Core некоторые поведения по умолчанию отличаются. Дополнительные сведения см. в разделе Стандартные параметры веб-приложений для JsonSerializerOptions.

К поддерживаемым типам относятся:

Дополнительные сведения см. в разделе Поддерживаемые типы коллекций в System.Text.Json.

Для обработки дополнительных типов или для обеспечения функциональности, которая не поддерживается встроенными преобразователями, можно реализовать пользовательские преобразователи.

Как считать JSON как объекты .NET (десериализация)

Распространенный способ десериализации JSON — сначала создать класс со свойствами и полями, представляющими одно или несколько свойств JSON. Затем, чтобы выполнить десериализацию из строки или файла, вызовите JsonSerializer.Deserialize метод . Для универсальных перегрузок вы передаете тип созданного класса в качестве параметра универсального типа. Для неуниверсических перегрузок вы передаете тип класса, созданного в качестве параметра метода. Десериализировать можно синхронно или асинхронно.

Все свойства 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, который вы хотите десериализовать, и у вас нет класса для десериализации, у вас есть варианты, отличные от создания нужного класса вручную:

  • Десериализируйте модель JSON DOM (объектную модель документов) и извлеките необходимые данные из модели DOM.

    Модель DOM позволяет перейти к подразделу полезных данных JSON и десериализовать одно значение, пользовательский тип или массив. Сведения о JsonNode модели DOM в .NET 6 см. в разделе Десериализация подразделов полезных данных JSON. Сведения о модели DOM см. в JsonDocument статье Поиск вложенных элементов JsonDocument и JsonElement.

  • Используйте Utf8JsonReader напрямую.

  • Используйте 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://docs.microsoft.com/dotnet/standard/serialization/system-text-json-how-to#visual-basic-support

Поведение десериализации

При десериализации JSON применяются следующие правила поведения:

При косвенном использовании System.Text.Json в приложении ASP.NET Core некоторые поведения по умолчанию отличаются. Дополнительные сведения см. в разделе Стандартные параметры веб-приложений для JsonSerializerOptions.

  • По умолчанию при сопоставлении имен свойств учитывается регистр. Вы можете указать учет регистра. Приложения ASP.NET Core указывают учет регистра по умолчанию.
  • Если JSON содержит значение для свойства, доступного только для чтения, значение игнорируется, а исключение не создается.
  • Для десериализации используется конструктор без параметров, который может быть общедоступным, внутренним или частным.
  • Десериализация неизменяемых объектов или свойств, у которых нет открытых set методов доступа, не поддерживается.
  • По умолчанию перечисления поддерживаются в виде чисел. Вы можете сериализовать имена перечислений в качестве строк.
  • Поля не поддерживаются.
  • По умолчанию комментарии или завершающие запятые в JSON вызывают исключения. Вы можете разрешить комментарии и завершающие запятые.
  • Максимальная глубина по умолчанию равна 64.

При косвенном использовании System.Text.Json в приложении ASP.NET Core некоторые поведения по умолчанию отличаются. Дополнительные сведения см. в разделе Стандартные параметры веб-приложений для JsonSerializerOptions.

Для обеспечения функциональности, которая не поддерживается встроенными преобразователями, можно реализовать пользовательские преобразователи.

Сериализация в форматированный JSON

Чтобы структурировать выходные данные JSON, задайте для JsonSerializerOptions.WriteIndented значение 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)

При многократном использовании JsonSerializerOptions с одинаковыми параметрами не создавайте новый экземпляр JsonSerializerOptions при каждом использовании. Повторно используйте один и тот же экземпляр для каждого вызова. Дополнительные сведения см. в разделе Повторное использование экземпляров JsonSerializerOptions.

Включение полей

Используйте глобальный параметр JsonSerializerOptions.IncludeFields или атрибут [JsonInclude] для включения поля при сериализации или десериализации, как показано ниже:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace Fields
{
    public class Forecast
    {
        public DateTime Date;
        public int TemperatureC;
        public string? Summary;
    }

    public class Forecast2
    {
        [JsonInclude]
        public DateTime Date;
        [JsonInclude]
        public int TemperatureC;
        [JsonInclude]
        public string? Summary;
    }

    public class Program
    {
        public static void Main()
        {
            var json =
                @"{""Date"":""2020-09-06T11:31:01.923395"",""TemperatureC"":-1,""Summary"":""Cold""} ";
            Console.WriteLine($"Input JSON: {json}");

            var options = new JsonSerializerOptions
            {
                IncludeFields = true,
            };
            var forecast = JsonSerializer.Deserialize<Forecast>(json, options)!;

            Console.WriteLine($"forecast.Date: {forecast.Date}");
            Console.WriteLine($"forecast.TemperatureC: {forecast.TemperatureC}");
            Console.WriteLine($"forecast.Summary: {forecast.Summary}");

            var roundTrippedJson =
                JsonSerializer.Serialize<Forecast>(forecast, options);

            Console.WriteLine($"Output JSON: {roundTrippedJson}");

            var forecast2 = JsonSerializer.Deserialize<Forecast2>(json)!;

            Console.WriteLine($"forecast2.Date: {forecast2.Date}");
            Console.WriteLine($"forecast2.TemperatureC: {forecast2.TemperatureC}");
            Console.WriteLine($"forecast2.Summary: {forecast2.Summary}");

            roundTrippedJson = JsonSerializer.Serialize<Forecast2>(forecast2);
            
            Console.WriteLine($"Output JSON: {roundTrippedJson}");
        }
    }
}

// Produces output like the following example:
//
//Input JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
//forecast.Date: 9/6/2020 11:31:01 AM
//forecast.TemperatureC: -1
//forecast.Summary: Cold
//Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
//forecast2.Date: 9/6/2020 11:31:01 AM
//forecast2.TemperatureC: -1
//forecast2.Summary: Cold
//Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
Imports System.Text.Json
Imports System.Text.Json.Serialization

Namespace Fields

    Public Class Forecast
        Public [Date] As Date
        Public TemperatureC As Integer
        Public Summary As String
    End Class

    Public Class Forecast2

        <JsonInclude>
        Public [Date] As Date

        <JsonInclude>
        Public TemperatureC As Integer

        <JsonInclude>
        Public Summary As String

    End Class

    Public NotInheritable Class Program

        Public Shared Sub Main()
            Dim json As String = "{""Date"":""2020-09-06T11:31:01.923395"",""TemperatureC"":-1,""Summary"":""Cold""}"
            Console.WriteLine($"Input JSON: {json}")

            Dim options As New JsonSerializerOptions With {
                .IncludeFields = True
            }
            Dim forecast1 As Forecast = JsonSerializer.Deserialize(Of Forecast)(json, options)

            Console.WriteLine($"forecast.Date: {forecast1.[Date]}")
            Console.WriteLine($"forecast.TemperatureC: {forecast1.TemperatureC}")
            Console.WriteLine($"forecast.Summary: {forecast1.Summary}")

            Dim roundTrippedJson As String = JsonSerializer.Serialize(forecast1, options)

            Console.WriteLine($"Output JSON: {roundTrippedJson}")

            Dim forecast21 As Forecast2 = JsonSerializer.Deserialize(Of Forecast2)(json)

            Console.WriteLine($"forecast2.Date: {forecast21.[Date]}")
            Console.WriteLine($"forecast2.TemperatureC: {forecast21.TemperatureC}")
            Console.WriteLine($"forecast2.Summary: {forecast21.Summary}")

            roundTrippedJson = JsonSerializer.Serialize(forecast21)

            Console.WriteLine($"Output JSON: {roundTrippedJson}")
        End Sub

    End Class

End Namespace

' Produces output like the following example:
'
'Input JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
'forecast.Date: 9/6/2020 11:31:01 AM
'forecast.TemperatureC: -1
'forecast.Summary: Cold
'Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
'forecast2.Date: 9/6/2020 11:31:01 AM
'forecast2.TemperatureC: -1
'forecast2.Summary: Cold
'Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}

Чтобы пропустить поля, предназначенные только для чтения, используйте глобальный параметр JsonSerializerOptions.IgnoreReadOnlyFields.

Поля не поддерживаются в System.Text.Json в .NET Core 3.1. Эта функция может быть предоставлена пользовательскими преобразователями.

Методы расширения HttpClient и HttpContent

Сериализация и десериализация полезных данных JSON из сети являются обычными операциями. Методы расширения в HttpClient и HttpContent позволяют выполнять эти операции в одной строке кода. Эти методы расширения используют стандартные параметры веб-приложений для JsonSerializerOptions.

В следующем примере демонстрируется применение HttpClientJsonExtensions.GetFromJsonAsync и HttpClientJsonExtensions.PostAsJsonAsync:

using System.Net.Http.Json;

namespace HttpClientExtensionMethods
{
    public class User
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Username { get; set; }
        public string? Email { get; set; }
    }

    public class Program
    {
        public static async Task Main()
        {
            using HttpClient client = new()
            {
                BaseAddress = new Uri("https://jsonplaceholder.typicode.com")
            };

            // Get the user information.
            User? user = await client.GetFromJsonAsync<User>("users/1");
            Console.WriteLine($"Id: {user?.Id}");
            Console.WriteLine($"Name: {user?.Name}");
            Console.WriteLine($"Username: {user?.Username}");
            Console.WriteLine($"Email: {user?.Email}");

            // Post a new user.
            HttpResponseMessage response = await client.PostAsJsonAsync("users", user);
            Console.WriteLine(
                $"{(response.IsSuccessStatusCode ? "Success" : "Error")} - {response.StatusCode}");
        }
    }
}

// Produces output like the following example but with different names:
//
//Id: 1
//Name: Tyler King
//Username: Tyler
//Email: Tyler @contoso.com
//Success - Created
Imports System.Net.Http
Imports System.Net.Http.Json

Namespace HttpClientExtensionMethods

    Public Class User
        Public Property Id As Integer
        Public Property Name As String
        Public Property Username As String
        Public Property Email As String
    End Class

    Public Class Program

        Public Shared Async Function Main() As Task
            Using client As New HttpClient With {
                .BaseAddress = New Uri("https://jsonplaceholder.typicode.com")
                }

                ' Get the user information.
                Dim user1 As User = Await client.GetFromJsonAsync(Of User)("users/1")
                Console.WriteLine($"Id: {user1.Id}")
                Console.WriteLine($"Name: {user1.Name}")
                Console.WriteLine($"Username: {user1.Username}")
                Console.WriteLine($"Email: {user1.Email}")

                ' Post a new user.
                Dim response As HttpResponseMessage = Await client.PostAsJsonAsync("users", user1)
                Console.WriteLine(
                $"{(If(response.IsSuccessStatusCode, "Success", "Error"))} - {response.StatusCode}")
            End Using
        End Function

    End Class

End Namespace

' Produces output like the following example but with different names:
'
'Id: 1
'Name: Tyler King
'Username: Tyler
'Email: Tyler @contoso.com
'Success - Created

Для System.Text.Json существуют также методы расширения на HttpContent.

Методы расширения на HttpClient и HttpContent недоступны в System.Text.Json для .NET Core 3.1.

См. также раздел