Udostępnij za pośrednictwem


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.Skip wartość. Aby zezwolić na końcowe przecinki, ustaw właściwość JsonSerializerOptions.AllowTrailingCommas na true. 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).

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 JsonSerializerOptions.NumberHandling, jak pokazano w przykładzie poniżej.

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 Run()
        {
            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 pisanie liczb ujętych w cudzysłów dla określonych właściwości, pól lub typów, użyj atrybutu [JsonNumberHandling].

Zobacz także