Jak zezwolić na niektóre rodzaje nieprawidłowych danych JSON za pomocą polecenia System.Text.Json

W tym artykule dowiesz się, jak zezwalać na komentarze, przecinki końcowe i cytowane liczby w formacie JSON oraz jak zapisywać liczby jako ciągi.

Zezwalaj na komentarze i końcowe przecinki

Domyślnie komentarze i końcowe przecinki nie są dozwolone w formacie JSON. Aby zezwolić na komentarze w formacie JSON, ustaw JsonSerializerOptions.ReadCommentHandling właściwość na JsonCommentHandling.Skipwartość . Aby zezwolić na końcowe przecinki, ustaw JsonSerializerOptions.AllowTrailingCommas właściwość na truewartość . W poniższym przykładzie pokazano, jak zezwolić na oba te elementy:

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)

Oto przykładowy kod JSON z komentarzami i końcowym przecinkiem:

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

Zezwalaj na liczby w cudzysłowie lub zapisuj je

Niektóre serializatory kodują liczby jako ciągi JSON (otoczone cudzysłowami).

Na przykład:

{
    "DegreesCelsius": "23"
}

Zamiast:

{
    "DegreesCelsius": 23
}

Aby serializować liczby w cudzysłowie lub akceptować liczby w cudzysłowie w całym grafie obiektu wejściowego, ustaw tak JsonSerializerOptions.NumberHandling , jak pokazano w poniższym przykładzie:

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

Jeśli używasz System.Text.Json pośrednio za pośrednictwem ASP.NET Core, liczby cytowane są dozwolone podczas deserializacji, ponieważ ASP.NET Core określa opcje domyślne sieci Web.

Aby zezwolić na określone właściwości, pola lub typy, użyj atrybutu [JsonNumberHandling].

Zobacz też