如何将 .NET 对象编写为 JSON(序列化)

本文演示如何使用 System.Text.Json 命名空间以序列化为 JavaScript 对象表示法 (JSON)。 如果要从 Newtonsoft.Json 移植现有代码,请参阅如何迁移到 System.Text.Json

提示

可以使用 AI 协助,通过 GitHub Copilot 序列化为 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";
            await using FileStream createStream = File.Create(fileName);
            await JsonSerializer.SerializeAsync(createStream, weatherForecast);

            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)

还可以使用 GitHub Copilot 为你生成序列化代码。 有关说明,请参阅本文中的使用 GitHub Copilot 部分。

序列化行为

当你在 ASP.NET Core 应用中间接使用 System.Text.Json 时,某些默认行为会有所不同。 有关详细信息,请参阅 JsonSerializerOptions 的 Web 默认值

支持的类型包括:

可以实现自定义转换器以处理其他类型或提供内置转换器不支持的功能。

以下示例演示了如何序列化包含集合属性和用户定义类型的类:

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)

还有一个采用 Utf8JsonWriterSerialize 重载可用。

序列化为格式化 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)

从 .NET 9 开始,还可以使用 IndentCharacterIndentSize 自定义缩进字符和大小。

提示

如果你通过相同的选项重复使用 JsonSerializerOptions,则请勿在每次使用时都创建新的 JsonSerializerOptions 实例。 对每个调用重复使用同一实例。 有关详细信息,请参阅重用 JsonSerializerOptions 实例

使用 GitHub Copilot 序列化为 JSON

可以在 IDE 中使用 GitHub Copilot,生成使用 System.Text.Json 序列化为 JSON 的代码。

如果使用的是 Visual Studio 2022 版本 17.8 或更高版本,则可以尝试通过 Visual Studio 中 AI 驱动的 GitHub Copilot 来生成使用 System.Text.Json 序列化为 JSON 的代码。 在 Copilot Chat 窗口中以提示形式提交问题,如下例所示。 还可以在编辑器窗口中使用内联聊天提交提示。

注意

GitHub Copilot 由 AI 提供支持,因此可能会带来意外和错误。 请确保验证任何生成的代码或建议。 有关 GitHub Copilot 的常规用途、产品影响、人工监督和隐私的更多信息,请参阅 GitHub Copilot 常见问题解答

以下文本显示了 Copilot 聊天的示例提示:

生成代码以使用 System.Text.Json 将对象序列化为 JSON 字符串。 对象包含以下字段:FirstName(字符串)、Lastname(字符串)、Age(整数)。 提供示例输出。

可以自定义提示,以使用符合要求的对象字段。

可以使用聊天功能(如斜杠命令、引用文件、方法或类和线程)来设置意向,并通过已限定范围上下文获取更好的答案。 对于在 IDE 中打开的项目中的现有类,可以使用 /generate code to serialize #Classname in #Filename to JSON 提示 GitHub Copilot。

以下输出显示了 Copilot 聊天响应示例:

Sure! Below is an example of how to use System.Text.Json to serialize an object with the specified fields to a JSON string in C#:

using System;
using System.Text.Json;

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main()
    {
        var person = new Person
        {
            FirstName = "John",
            LastName = "Doe",
            Age = 30
        };

        string jsonString = JsonSerializer.Serialize(person);
        Console.WriteLine(jsonString);
    }
}

**Example Output**
{"FirstName":"John","LastName":"Doe","Age":30}

This code defines a `Person` class, creates an instance of it, and then serializes it to a JSON string using `JsonSerializer.Serialize`. The resulting JSON string is then printed to the console.

当 Copilot 返回代码块时,响应包括用于复制代码、将代码插入新文件或预览代码输出的选项。

注意

结果可能与示例响应中显示的结果不同。 AI 模型不确定,这意味着当被问及相同的问题时,它们可以返回不同的响应。 这可能是由于一段时间内进行的额外学习和调整、语言变体、上下文中的更改(如聊天历史记录等)。

动画屏幕截图,显示使用 Visual Studio 中的 GitHub Copilot Chat 将对象序列化为 JSON 字符串。

有关详细信息,请参阅: