Разрешение некоторых недопустимых объектов JSON с помощью System.Text.Json

Из этой статьи вы узнаете, как разрешить комментарии, конечные запятые и числа в кавычках при сериализации в JSON и как записывать числа в виде строк.

Разрешение комментариев и завершающих запятых

По умолчанию комментарии и завершающие запятые в JSON не допускаются. Чтобы разрешить комментарии в JSON, задайте для свойства JsonSerializerOptions.ReadCommentHandling значение JsonCommentHandling.Skip. Чтобы разрешить завершающие запятые, задайте для свойства JsonSerializerOptions.AllowTrailingCommas значение true. В следующем примере показано, как разрешить оба варианта:

var options = new JsonSerializerOptions
{
    ReadCommentHandling = JsonCommentHandling.Skip,
    AllowTrailingCommas = true,
};
WeatherForecast weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
    jsonString,
    options
    )!;
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .ReadCommentHandling = JsonCommentHandling.Skip,
    .AllowTrailingCommas = True
}
Dim weatherForecast1 = JsonSerializer.Deserialize(Of WeatherForecast)(jsonString, options)

Ниже приведен пример JSON с комментариями и завершающей запятой:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25, // Fahrenheit 77
  "Summary": "Hot", /* Zharko */
  // Comments on
  /* separate lines */
}

Разрешение или запись чисел в кавычках

Некоторые сериализаторы кодируют числа в виде строк JSON (заключены в кавычки).

Например:

{
    "DegreesCelsius": "23"
}

Вместо:

{
    "DegreesCelsius": 23
}

Для сериализации или принятия чисел в кавычках во всех входных данных графа объектов задайте свойство JsonSerializerOptions.NumberHandling, как показано ниже:

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

namespace QuotedNumbers
{
    public class Forecast
    {
        public DateTime Date { get; init; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
    };

    public class Program
    {
        public static void Main()
        {
            Forecast forecast = new()
            {
                Date = DateTime.Now,
                TemperatureC = 40,
                Summary = "Hot"
            };

            JsonSerializerOptions options = new()
            {
                NumberHandling =
                    JsonNumberHandling.AllowReadingFromString |
                    JsonNumberHandling.WriteAsString,
                WriteIndented = true
            };

            string forecastJson =
                JsonSerializer.Serialize<Forecast>(forecast, options);

            Console.WriteLine($"Output JSON:\n{forecastJson}");

            Forecast forecastDeserialized =
                JsonSerializer.Deserialize<Forecast>(forecastJson, options)!;

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

// Produces output like the following example:
//
//Output JSON:
//{
//  "Date": "2020-10-23T12:27:06.4017385-07:00",
//  "TemperatureC": "40",
//  "Summary": "Hot"
//}
//Date: 10/23/2020 12:27:06 PM
//TemperatureC: 40
//Summary: Hot
Imports System.Text.Json
Imports System.Text.Json.Serialization

Namespace QuotedNumbers

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

    Public NotInheritable Class Program

        Public Shared Sub Main()
            Dim forecast1 As New Forecast() With {
                .[Date] = Date.Now,
                .TemperatureC = 40,
                .Summary = "Hot"
                }

            Dim options As New JsonSerializerOptions() With {
                .NumberHandling = JsonNumberHandling.AllowReadingFromString Or
                        JsonNumberHandling.WriteAsString,
                .WriteIndented = True
                }

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

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

            Dim forecastDeserialized As Forecast = JsonSerializer.Deserialize(Of Forecast)(forecastJson, options)

            Console.WriteLine($"Date: {forecastDeserialized.[Date]}")
            Console.WriteLine($"TemperatureC: {forecastDeserialized.TemperatureC}")
            Console.WriteLine($"Summary: {forecastDeserialized.Summary}")
        End Sub

    End Class

End Namespace

' Produces output like the following example:
'
'Output JSON:
'{
'  "Date": "2020-10-23T12:27:06.4017385-07:00",
'  "TemperatureC": "40",
'  "Summary": "Hot"
'}
'Date: 10/23/2020 12:27:06 PM
'TemperatureC: 40
'Summary: Hot

Если вы используете System.Text.Json косвенно через ASP.NET Core, тогда заключенные в кавычки числа будут разрешены при десериализации, поскольку ASP.NET Core определяет стандартные параметры веб-приложений.

Чтобы разрешить или записать заключенные в кавычки числа для конкретных свойств, полей или типов, используйте атрибут [JsonNumberHandling].

См. также