System.Text.Json 中支援的型別
本文概述串行化和還原串行化支援哪些類型。
串行化為 JSON 物件的類型
下列型態會串行化為 JSON 物件:
- 類別*
- 結構
- 介面
- 記錄和結構記錄
* 實作 IEnumerable<T> 串行化為 JSON 陣列的非字典類型。 實作 IEnumerable<T>的字典類型,會串行化為 JSON 物件。
下列代碼段顯示簡單結構的串行化。
public static void Main()
{
var coordinates = new Coords(1.0, 2.0);
string json = JsonSerializer.Serialize(coordinates);
Console.WriteLine(json);
// Output:
// {"X":1,"Y":2}
}
public readonly struct Coords
{
public Coords(double x, double y)
{
X = x;
Y = y;
}
public double X { get; }
public double Y { get; }
}
串行化為 JSON 陣列的類型
.NET 集合類型會串行化為 JSON 陣列。 如果串行化,System.Text.Json.JsonSerializer 支援集合類型:
- 衍生自 IEnumerable 或 IAsyncEnumerable<T>。
- 包含可串行化的元素。
串行化程式會呼叫 GetEnumerator() 方法,並寫入 專案。
還原串行化比較複雜,而且某些集合類型不支援。
下列各節會依命名空間組織,並顯示串行化和還原串行化支援哪些類型。
- System.Array 命名空間
- System.Collections 命名空間
- System.Collections.Generic 命名空間
- System.Collections.Immutable 命名空間
- System.Collections.Specialized 命名空間
- System.Collections.Concurrent 命名空間
- System.Collections.ObjectModel 命名空間
- 自定義集合
System.Array 命名空間
類型 | 序列化 | 還原串行化 |
---|---|---|
單維陣列 | ✔️ | ✔️ |
多維度陣列 | ❌ | ❌ |
Jagged 陣組 | ✔️ | ✔️ |
System.Collections 命名空間
類型 | 序列化 | 還原串行化 |
---|---|---|
ArrayList | ✔️ | ✔️ |
BitArray | ✔️ | ❌ |
DictionaryEntry | ✔️ | ✔️ |
Hashtable | ✔️ | ✔️ |
ICollection | ✔️ | ✔️ |
IDictionary | ✔️ | ✔️ |
IEnumerable | ✔️ | ✔️ |
IList | ✔️ | ✔️ |
Queue | ✔️ | ✔️ |
SortedList | ✔️ | ✔️ |
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>
一節。
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> * | ✔️ | ✔️ |
* 請參閱
†請參閱
System.Collections.Specialized 命名空間
類型 | 序列化 | 還原串行化 |
---|---|---|
BitVector32 | ✔️ | ❌* |
HybridDictionary | ✔️ | ✔️ |
IOrderedDictionary | ✔️ | ❌ |
ListDictionary | ✔️ | ✔️ |
NameValueCollection | ✔️ | ❌ |
StringCollection | ✔️ | ❌ |
StringDictionary | ✔️ | ❌ |
* 還原串行化 BitVector32 時,會略過 Data 屬性,因為它沒有公用 setter。 不會擲回例外狀況。
System.Collections.Concurrent 命名空間
類型 | 序列化 | 還原串行化 |
---|---|---|
BlockingCollection<T> | ✔️ | ❌ |
ConcurrentBag<T> | ✔️ | ❌ |
ConcurrentDictionary<TKey,TValue> † | ✔️ | ✔️ |
ConcurrentQueue<T> | ✔️ | ✔️ |
ConcurrentStack<T> * | ✔️ | ✔️ |
* 請參閱
†請參閱
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> *
* 請參閱
類型的 支援來回行程。 †請參閱
支援的金鑰類型。
已知問題
下列自訂集合有已知問題:
- 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。
如需已知問題的詳細資訊,請參閱
支援的金鑰類型
當做 Dictionary
和 SortedList
類型的索引鍵使用時,下列類型具有內建支援:
Boolean
Byte
DateTime
DateTimeOffset
Decimal
Double
Enum
Guid
Int16
Int32
Int64
-
Object
(只有在串行化上,且運行時間類型是此清單中的其中一個支援型別。 SByte
Single
String
- TimeSpan
UInt16
UInt32
UInt64
- Uri
- Version
此外,JsonConverter<T>.WriteAsPropertyName(Utf8JsonWriter, T, JsonSerializerOptions) 和 JsonConverter<T>.ReadAsPropertyName(Utf8JsonReader, Type, JsonSerializerOptions) 方法可讓您新增您選擇的任何類型的字典索引鍵支援。
不支援的類型
序列化不支援下列型態:
- System.Type 和 System.Reflection.MemberInfo
- 一般 ReadOnlySpan<T>、Span<T>和 ref 結構
- 委派類型
- IntPtr 和 UIntPtr
System.Data 命名空間
DataSet、DataTable和 System.Data 命名空間中的相關類型沒有內建轉換器。 從不受信任的輸入還原串行化這些類型並不安全,如 安全性指導方針中所述,。 不過,您可以撰寫自定義轉換器來支援這些類型。 如需串行化和還原串行化 DataTable
的範例自定義轉換器程式代碼,請參閱 RoundtripDataTable.cs。