使用英语阅读

通过


如何使用 System.Text.Json 支持某种无效的 JSON

本文将介绍如何能够在 JSON 中使用注释、尾随逗号和带引号的数字,以及如何将数字编写为字符串。

允许注释和尾随逗号

默认情况下,JSON 中不允许使用注释和尾随逗号。 若要在 JSON 中允许注释,请将 JsonSerializerOptions.ReadCommentHandling 属性设置为 JsonCommentHandling.Skip。 若要允许尾随逗号,请将 JsonSerializerOptions.AllowTrailingCommas 属性设置为 true。 下面的示例演示如何允许这两者:

C#
var options = new JsonSerializerOptions
{
    ReadCommentHandling = JsonCommentHandling.Skip,
    AllowTrailingCommas = true,
};
WeatherForecast weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
    jsonString,
    options
    )!;

下面是包含注释和尾随逗号的示例 JSON:

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

允许或写入带引号的数字

某些序列化程序将数字编码为 JSON 字符串(括在引号中)。

例如:

JSON
{
    "DegreesCelsius": "23"
}

不是:

JSON
{
    "DegreesCelsius": 23
}

若要在整个输入对象图中序列化带引号的数字或接受带引号的数字,请设置 JsonSerializerOptions.NumberHandling,如以下示例中所示:

C#
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

在通过 ASP.NET Core 间接使用 System.Text.Json 时,反序列化时允许使用带引号的数字,因为 ASP.NET Core 指定 Web 默认选项

若要允许或写入特定属性、字段或类型的带引号的数字,请使用 [JsonNumberHandling] 特性。

请参阅