Obsługiwane typy w System.Text.Json
Ten artykuł zawiera omówienie typów obsługiwanych w przypadku serializacji i deserializacji.
Typy serializujące jako obiekty JSON
Następujące typy serializują się jako obiekty JSON:
- Klasy*
- Struktury
- Interfejsów
- Rekordy i rekordy struktury
* Typy inne niż słowniki, które implementują IEnumerable<T> serializować jako tablice JSON. Typy słowników, które implementują IEnumerable<T>, serializują jako obiekty JSON.
Poniższy fragment kodu przedstawia serializacji prostej struktury.
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; }
}
Typy, które serializują się jako tablice JSON
Typy kolekcji .NET serializują się jako tablice JSON. System.Text.Json.JsonSerializer obsługuje typ kolekcji dla serializacji, jeśli:
- Pochodzi z IEnumerable lub IAsyncEnumerable<T>.
- Zawiera elementy, które można serializować.
Serializator wywołuje metodę GetEnumerator() i zapisuje elementy.
Deserializacja jest bardziej skomplikowana i nie jest obsługiwana w przypadku niektórych typów kolekcji.
Poniższe sekcje są uporządkowane według przestrzeni nazw i pokazują, które typy są obsługiwane w przypadku serializacji i deserializacji.
- przestrzeni nazw System.Array
- przestrzeni nazw System.Collections
- Przestrzeni nazw System.Collections.Generic
- przestrzeni nazw System.Collections.Niezmienna
- System.Collections.Specialized przestrzeni nazw
- System.Collections.Concurrent przestrzeni nazw
- przestrzeni nazw System.Collections.ObjectModel
- kolekcje niestandardowe
Przestrzeń nazw System.Array
Typ | Szeregowanie | Deserializacja |
---|---|---|
tablice jednowymiarowe | ✔️ | ✔️ |
tablic wielowymiarowych | ❌ | ❌ |
tablice jagged | ✔️ | ✔️ |
Przestrzeń nazw System.Collections
Typ | Szeregowanie | Deserializacja |
---|---|---|
ArrayList | ✔️ | ✔️ |
BitArray | ✔️ | ❌ |
DictionaryEntry | ✔️ | ✔️ |
Hashtable | ✔️ | ✔️ |
ICollection | ✔️ | ✔️ |
IDictionary | ✔️ | ✔️ |
IEnumerable | ✔️ | ✔️ |
IList | ✔️ | ✔️ |
Queue | ✔️ | ✔️ |
SortedList | ✔️ | ✔️ |
Stack * | ✔️ | ✔️ |
* Zobacz Support round trip for Stack
types.
System.Collections.Generic, przestrzeń nazw
Typ | Szeregowanie | Deserializacja |
---|---|---|
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> ‹ | ✔️ | ✔️ |
* Zobacz Obsługiwane typy kluczy.
† Zobacz następującą sekcję w IAsyncEnumerable<T>
.
‹ Zobacz Pomoc techniczna dla typów Stack
.
IAsyncEnumerable<T>
W poniższych przykładach strumienie są używane jako reprezentacja dowolnego asynchronicznego źródła danych. Źródłem mogą być pliki na komputerze lokalnym lub wyniki z zapytania bazy danych lub wywołania interfejsu API usługi internetowej.
Serializacja strumienia
System.Text.Json
obsługuje serializowanie wartości IAsyncEnumerable<T> jako tablic JSON, jak pokazano w poniższym przykładzie:
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>
wartości są obsługiwane tylko przez metody serializacji asynchronicznej, takie jak JsonSerializer.SerializeAsync.
Deserializacja strumienia
Metoda DeserializeAsyncEnumerable
obsługuje deserializacji przesyłania strumieniowego, jak pokazano w poniższym przykładzie:
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
Metoda DeserializeAsyncEnumerable
obsługuje tylko odczytywanie z tablic JSON na poziomie głównym.
Metoda DeserializeAsync obsługuje IAsyncEnumerable<T>
, ale jej podpis nie zezwala na przesyłanie strumieniowe. Zwraca końcowy wynik jako pojedynczą wartość, jak pokazano w poniższym przykładzie.
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
W tym przykładzie deserializator buforuje całą zawartość IAsyncEnumerable<T>
w pamięci przed zwróceniem zdeserializowanego obiektu. To zachowanie jest konieczne, ponieważ deserializator musi odczytać cały ładunek JSON przed zwróceniem wyniku.
System.Collections.Niezmienna przestrzeń nazw
Typ | Szeregowanie | Deserializacja |
---|---|---|
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> * | ✔️ | ✔️ |
* Zobacz Support round trip for Stack
types.
† Zobacz Obsługiwane typy kluczy.
System.Collections.Wyspecjalizowana przestrzeń nazw
Typ | Szeregowanie | Deserializacja |
---|---|---|
BitVector32 | ✔️ | ❌* |
HybridDictionary | ✔️ | ✔️ |
IOrderedDictionary | ✔️ | ❌ |
ListDictionary | ✔️ | ✔️ |
NameValueCollection | ✔️ | ❌ |
StringCollection | ✔️ | ❌ |
StringDictionary | ✔️ | ❌ |
* W przypadku deserializacji BitVector32 właściwość Data jest pomijana, ponieważ nie ma publicznego zestawu. Nie jest zgłaszany żaden wyjątek.
System.Collections.Concurrent, przestrzeń nazw
Typ | Szeregowanie | Deserializacja |
---|---|---|
BlockingCollection<T> | ✔️ | ❌ |
ConcurrentBag<T> | ✔️ | ❌ |
ConcurrentDictionary<TKey,TValue> † | ✔️ | ✔️ |
ConcurrentQueue<T> | ✔️ | ✔️ |
ConcurrentStack<T> * | ✔️ | ✔️ |
* Zobacz Support round trip for Stack
types.
† Zobacz Obsługiwane typy kluczy.
Przestrzeń nazw System.Collections.ObjectModel
Typ | Szeregowanie | Deserializacja |
---|---|---|
Collection<T> | ✔️ | ✔️ |
ciąg KeyedCollection<, TValue> * | ✔️ | ❌ |
ObservableCollection<T> | ✔️ | ✔️ |
ReadOnlyCollection<T> | ✔️ | ❌ |
ReadOnlyDictionary<TKey,TValue> | ✔️ | ❌ |
ReadOnlyObservableCollection<T> | ✔️ | ❌ |
* Klucze inne niżstring
nie są obsługiwane.
Kolekcje niestandardowe
Każdy typ kolekcji, który nie znajduje się w jednej z poprzednich przestrzeni nazw, jest uważany za kolekcję niestandardową. Takie typy obejmują typy zdefiniowane przez użytkownika i typy zdefiniowane przez ASP.NET Core. Na przykład Microsoft.Extensions.Primitives znajduje się w tej grupie.
Wszystkie kolekcje niestandardowe (wszystkie kolekcje pochodzące z IEnumerable
) są obsługiwane do serializacji, o ile ich typy elementów są obsługiwane.
Obsługa deserializacji
Kolekcja niestandardowa jest obsługiwana w przypadku deserializacji, jeśli:
Nie jest interfejsem ani abstrakcją.
Ma konstruktor bez parametrów.
Zawiera typy elementów obsługiwane przez JsonSerializer.
Implementuje lub dziedziczy co najmniej jeden z następujących interfejsów lub klas:
- ConcurrentQueue<T>
- ConcurrentStack<T> *
- ICollection<T>
- IDictionary
- IDictionary<TKey,TValue> †
- IList
- IList<T>
- Queue
- Queue<T>
- Stack *
- Stack<T> *
* Zobacz Support round trip for
Stack
types.† Zobacz Obsługiwane typy kluczy.
Znane problemy
Istnieją znane problemy z następującymi kolekcjami niestandardowymi:
- ExpandoObject: zobacz dotnet/runtime#29690.
- DynamicObject: zobacz dotnet/runtime#1808.
- DataTable: zobacz dotnet/docs#21366.
- Microsoft.AspNetCore.Http.FormFile: zobacz dotnet/runtime#1559.
- Microsoft.AspNetCore.Http.IFormCollection: zobacz dotnet/runtime#1559.
Aby uzyskać więcej informacji na temat znanych problemów, zobacz otwarte problemy w programie System.Text.Json.
Obsługiwane typy kluczy
W przypadku użycia jako kluczy typów Dictionary
i SortedList
następujące typy mają wbudowaną obsługę:
Boolean
Byte
DateTime
DateTimeOffset
Decimal
Double
Enum
Guid
Int16
Int32
Int64
-
Object
(tylko w przypadku serializacji i jeśli typ środowiska uruchomieniowego jest jednym z obsługiwanych typów na tej liście). SByte
Single
String
- TimeSpan
UInt16
UInt32
UInt64
- Uri
- Version
Ponadto metody JsonConverter<T>.WriteAsPropertyName(Utf8JsonWriter, T, JsonSerializerOptions) i JsonConverter<T>.ReadAsPropertyName(Utf8JsonReader, Type, JsonSerializerOptions) umożliwiają dodanie obsługi klucza słownika dla dowolnego typu wybranego typu.
Nieobsługiwane typy
Następujące typy nie są obsługiwane w przypadku serializacji:
- System.Type i System.Reflection.MemberInfo
- ogólne struktury ReadOnlySpan<T>, Span<T>i ref
- Typy delegatów
- IntPtr i UIntPtr
Przestrzeń nazw System.Data
Brak wbudowanych konwerterów dla DataSet, DataTablei powiązanych typów w przestrzeni nazw System.Data. Deserializowanie tych typów z niezaufanych danych wejściowych nie jest bezpieczne, jak wyjaśniono w wskazówki dotyczące zabezpieczeń. Można jednak napisać konwerter niestandardowy, aby obsługiwać te typy. Aby uzyskać przykładowy kod konwertera niestandardowego, który serializuje i deserializuje DataTable
, zobacz RoundtripDataTable.cs.
Zobacz też
- Wypełnij zainicjowane właściwości
- omówienie System.Text.Json
- dokumentacja interfejsu API System.Text.Json
- System.Text.Json. Dokumentacja interfejsu API serializacji