Поддерживаемые типы коллекций в System.Text.Json
В этой статье приводятся общие сведения о том, какие коллекции поддерживаются для сериализации и десериализации. System.Text.Json.JsonSerializer поддерживает тип коллекции для сериализации, если он:
- Производные от IEnumerable или IAsyncEnumerable<T>
- Содержит элементы, сериализуемые.
Сериализатор вызывает 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>
В следующих примерах потоки используются в качестве представления любого асинхронного источника данных. Источник может быть файлами на локальном компьютере или результатом вызова API базы данных или 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.Специализированное пространство имен
Тип | Сериализация | Десериализация |
---|---|---|
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<, TValue> * | ✔️ | ❌ |
ObservableCollection<T> | ✔️ | ✔️ |
ReadOnlyCollection<T> | ✔️ | ❌ |
ReadOnlyDictionary<TKey,TValue> | ✔️ | ❌ |
ReadOnlyObservableCollection<T> | ✔️ | ❌ |
string
* Не поддерживаются ключи.
Настраиваемые коллекции
Любой тип коллекции, который не находится в одном из предыдущих пространств имен, считается пользовательской коллекцией. Такие типы включают определяемые пользователем типы и типы, определенные ASP.NET Core. Например, Microsoft.Extensions.Primitives находится в этой группе.
Все пользовательские коллекции (все, производные от IEnumerable
) поддерживаются для сериализации, если поддерживаются их типы элементов.
Пользовательские коллекции с поддержкой десериализации
Пользовательская коллекция поддерживается для десериализации, если она:
Не является интерфейсом или абстрактным.
Имеет конструктор без параметров.
Содержит типы элементов, поддерживаемые JsonSerializer.
Реализует или наследует один или несколько следующих интерфейсов или классов:
- ConcurrentQueue<T>
- ConcurrentStack<T> *
- ICollection<T>
- IDictionary
- IDictionary<TKey,TValue> †
- IList
- IList<T>
- Queue
- Queue<T>
- Stack *
- Stack<T> *
* См . круговую поездку в службу поддержки для
Stack
типов.† См . поддерживаемые типы ключей.
Пользовательские коллекции с известными проблемами
Существуют известные проблемы со следующими настраиваемыми коллекциями:
- ExpandoObject: см . dotnet/runtime#29690.
- DynamicObject: см . dotnet/runtime#1808.
- DataTable: см . dotnet/docs#21366.
- Microsoft.AspNetCore.Http.FormFile: см . dotnet/runtime#1559.
- Microsoft.AspNetCore.Http.IFormCollection: см . dotnet/runtime#1559.
Дополнительные сведения об известных проблемах см. в System.Text.Jsonразделе об открытых проблемах.
Поддерживаемые типы ключей
Поддерживаемые типы для ключей Dictionary
и SortedList
типов включают следующие:
Boolean
Byte
DateTime
DateTimeOffset
Decimal
Double
Enum
Guid
Int16
Int32
Int64
Object
(Только при сериализации и если тип среды выполнения является одним из поддерживаемых типов в этом списке.)SByte
Single
String
UInt16
UInt32
UInt64
Пространство имен System.Data
Встроенные преобразователи для DataSetи DataTableсвязанных типов в System.Data пространстве имен отсутствуют. Десериализация этих типов из ненадежных входных данных не является безопасной, как описано в руководстве по безопасности. Однако можно написать пользовательский преобразователь для поддержки этих типов. Пример пользовательского кода преобразователя, который сериализует и десериализирует a DataTable
, см. в разделе RoundtripDataTable.cs.