System.Text.Json 中支持的集合类型

本文概述了可进行序列化和反序列化的集合的概述。 System.Text.Json.JsonSerializer 支持将集合类型进行序列化,只要集合类型满足以下条件:

序列化程序调用 GetEnumerator() 方法并写入元素。

反序列化更为复杂,并且某些集合类型不支持反序列化。

以下各节按命名空间划分,并显示序列化和反序列化支持的类型。

System.Array 命名空间

类型 序列化 反序列化
一维数组
多维数组
交错数组

System.Collections 命名空间

类型 序列化 反序列化
ArrayList
BitArray
DictionaryEntry
Hashtable
ICollection
IDictionary
IEnumerable
IList
Queue
SortedList
Stack *

* 请参阅支持 Stack 类型的往返

System.Collections.Generic 命名空间

类型 序列化 反序列化
Dictionary<TKey,TValue> *
HashSet<T>
IAsyncEnumerable<T>
ICollection<T>
IDictionary<TKey,TValue> *
IEnumerable<T>
IList<T>
IReadOnlyCollection<T>
IReadOnlyDictionary<TKey,TValue> *
IReadOnlyList<T>
ISet<T>
KeyValuePair<TKey,TValue>
LinkedList<T>
LinkedListNode<T>
List<T>
Queue<T>
SortedDictionary<TKey,TValue> *
SortedList<TKey,TValue> *
SortedSet<T>
Stack<T>

* 请参阅支持的密钥类型

† 请参阅下面有关 IAsyncEnumerable<T> 的部分。

‡ 请参阅支持 Stack 类型的往返

IAsyncEnumerable<T>

下面的示例使用流作为数据的任何异步源的表示形式。 源可以是本地计算机上的文件,也可以是数据库查询或 Web 服务 API 调用的结果。

流序列化

System.Text.Json 支持将 IAsyncEnumerable<T> 值序列化为 JSON 数组,如下面的示例所示:

using System.Text.Json;

namespace IAsyncEnumerableSerialize;

public class Program
{
    public static async Task Main()
    {
        using Stream stream = Console.OpenStandardOutput();
        var data = new { Data = PrintNumbers(3) };
        await JsonSerializer.SerializeAsync(stream, data);
    }

    static async IAsyncEnumerable<int> PrintNumbers(int n)
    {
        for (int i = 0; i < n; i++)
        {
            await Task.Delay(1000);
            yield return i;
        }
    }
}
// output:
//  {"Data":[0,1,2]}

IAsyncEnumerable<T> 值仅受异步序列化方法(如 JsonSerializer.SerializeAsync)支持。

流反序列化

DeserializeAsyncEnumerable 方法支持流式反序列化,如下面的示例所示:

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

namespace IAsyncEnumerableDeserialize;

public class Program
{
    public static async Task Main()
    {
        using var stream = new MemoryStream(Encoding.UTF8.GetBytes("[0,1,2,3,4]"));
        await foreach (int item in JsonSerializer.DeserializeAsyncEnumerable<int>(stream))
        {
            Console.WriteLine(item);
        }
    }
}
// output:
//0
//1
//2
//3
//4

DeserializeAsyncEnumerable 方法仅支持从根级 JSON 数组进行读取。

DeserializeAsync 方法支持 IAsyncEnumerable<T>,但其签名不允许流式处理。 它将返回一个值作为最终结果,如下面的示例所示。

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

namespace IAsyncEnumerableDeserializeNonStreaming;

public class MyPoco
{
    public IAsyncEnumerable<int>? Data { get; set; }
}

public class Program
{
    public static async Task Main()
    {
        using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"{""Data"":[0,1,2,3,4]}"));
        MyPoco? result = await JsonSerializer.DeserializeAsync<MyPoco>(stream)!;
        await foreach (int item in result!.Data!)
        {
            Console.WriteLine(item);
        }
    }
}
// output:
//0
//1
//2
//3
//4

在此示例中,反序列化程序在返回反序列化的对象之前,它会在内存中缓冲所有 IAsyncEnumerable<T> 内容。 此行为是必需的,因为反序列化程序在返回结果之前,它需要读取整个 JSON 有效负载。

System.Collections.Immutable 命名空间

类型 序列化 反序列化
IImmutableDictionary<TKey,TValue>
IImmutableList<T>
IImmutableQueue<T>
IImmutableSet<T>
IImmutableStack<T> *
ImmutableArray<T>
ImmutableDictionary<TKey,TValue>
ImmutableHashSet<T>
ImmutableQueue<T>
ImmutableSortedDictionary<TKey,TValue>
ImmutableSortedSet<T>
ImmutableStack<T> *

* 请参阅支持 Stack 类型的往返

† 请参阅支持的密钥类型

System.Collections.Specialized 命名空间

类型 序列化 反序列化
BitVector32 ❌*
HybridDictionary
IOrderedDictionary
ListDictionary
NameValueCollection
StringCollection
StringDictionary

* 反序列化 BitVector32 时将跳过 Data 属性,因为它没有公共资源库。 不会引发异常。

System.Collections.Concurrent 命名空间

类型 序列化 反序列化
BlockingCollection<T>
ConcurrentBag<T>
ConcurrentDictionary<TKey,TValue>
ConcurrentQueue<T>
ConcurrentStack<T> *

* 请参阅支持 Stack 类型的往返

† 请参阅支持的密钥类型

System.Collections.ObjectModel 命名空间

类型 序列化 反序列化
Collection<T>
KeyedCollection<string, TValue> *
ObservableCollection<T>
ReadOnlyCollection<T>
ReadOnlyDictionary<TKey,TValue>
ReadOnlyObservableCollection<T>

* 不支持非 string 密钥。

自定义集合

不在上述任一命名空间中的任何集合类型都视为自定义集合。 此类类型包括用户定义的类型和 ASP.NET Core 定义的类型。 例如,Microsoft.Extensions.Primitives 位于此组中。

只要元素类型受支持,则所有自定义类集合(派生自 IEnumerable 的任何内容)都可进行序列化。

支持反序列化的自定义集合

如果自定义集合符合以下条件,则可进行反序列化:

具有已知问题的自定义集合

以下自定义集合存在已知问题:

有关已知问题详细信息,请参阅 System.Text.Json 中的未解决问题

支持的密钥类型

DictionarySortedList 的密钥支持的类型包括:

  • Boolean
  • Byte
  • DateTime
  • DateTimeOffset
  • Decimal
  • Double
  • Enum
  • Guid
  • Int16
  • Int32
  • Int64
  • Object(仅针对序列化,并且运行时类型是此列表中的支持类型之一。)
  • SByte
  • Single
  • String
  • UInt16
  • UInt32
  • UInt64

System.Data 命名空间

System.Data 命名空间中没有用于 DataSetDataTable 和相关类型的内置转换器。 从不受信任的输入中反序列化这些类型不安全,如安全指南中所述。 但是,可以编写自定义转换器来支持这些类型。 有关序列化并反序列化 DataTable 的示例自定义转换器代码,请参阅 RoundtripDataTable.cs

另请参阅