System.Text.Json 지원되는 형식

이 문서에서는 serialization 및 deserialization에 지원되는 형식에 대한 개요를 제공합니다.

JSON 개체로 직렬화하는 형식

다음 형식은 JSON 개체로 직렬화합니다.

  • 클래스*
  • 구조체
  • 인터페이스
  • 레코드 및 구조체 레코드

* JSON 배열로 직렬화할 IEnumerable<T> 구현하는 사전이 아닌 형식입니다. IEnumerable<T>구현하는 사전 형식은 JSON 개체로 직렬화됩니다.

다음 코드 조각은 간단한 구조체의 serialization을 보여줍니다.

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 다음과 같은 경우 serialization을 위한 컬렉션 형식을 지원합니다.

serializer는 GetEnumerator() 메서드를 호출하고 요소를 씁니다.

역직렬화는 더 복잡하며 일부 컬렉션 형식에서는 지원되지 않습니다.

다음 섹션은 네임스페이스별로 구성되며 직렬화 및 역직렬화에 지원되는 형식을 보여 있습니다.

  • System.Array 네임스페이스
  • System.Collections 네임스페이스
  • System.Collections.Generic 네임스페이스
  • system.Collections.Immutable 네임스페이스
  • System.Collections.Specialized 네임스페이스
  • system.Collections.Concurrent 네임스페이스
  • System.Collections.ObjectModel 네임스페이스
  • 사용자 지정 컬렉션

System.Array 네임스페이스

형 직렬화 역직렬화
1차원 배열* ✔️ ✔️
다차원 배열 ❌ ❌
가변 배열 ✔️ ✔️

* byte[] 는 특별히 처리되고 JSON 배열이 아닌 base64 문자열로 직렬화됩니다.

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> ✔️ ✔️
IReadOnlySet<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>다음 섹션을 참조하세요.

• 유형은 지원 왕복을 참조하세요.

§ System.Text.Json .NET 11 이상 버전에서 지원합니다IReadOnlySet<T>. 인터페이스를 역직렬화하면 serializer가 인스턴스를 HashSet<T> 만듭니다. 생성된 메타데이터 JsonMetadataServices.CreateIReadOnlySetInfo 의 경우 컬렉션 계약을 만듭니다.

IAsyncEnumerable<T>

다음 예제에서는 비동기 데이터 원본의 표현으로 스트림을 사용합니다. 원본은 로컬 컴퓨터의 파일이거나 데이터베이스 쿼리 또는 웹 서비스 API 호출의 결과일 수 있습니다.

스트림 serialization

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같은 비동기 serialization 메서드에서만 지원됩니다.

.NET 11 이상 버전 JsonSerializer.SerializeAsyncEnumerable 에서 시퀀스를 IAsyncEnumerable<T> a 또는 a StreamPipeWriter에 씁니다. 기본값 topLevelValues: false을 사용하여 메서드는 단일 루트 수준 JSON 배열을 씁니다. 각 요소가 별도의 최상위 값인 JSON 줄을 대신 쓰도록 설정합니다topLevelValues: true.

{"id":1,"name":"apple"}
{"id":2,"name":"banana"}

메서드는 마지막을 포함하여 모든 값 다음에 LF(단일 줄 바꿈) \n를 씁니다. 에 관계없이 항상 LF를 JsonSerializerOptions.NewLine사용합니다. 메서드는 무시 JsonSerializerOptions.WriteIndented하므로 각 값은 한 줄에 유지됩니다.

스트림 역직렬화

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

기본적으로 JsonSerializer.DeserializeAsyncEnumerable 단일 루트 수준 JSON 배열에서 요소를 읽습니다. 대신 공백으로 구분된 최상위 값 시퀀스를 읽도록 설정합니다 topLevelValues: true . 이 입력 형식은 JSON 선의 상위 집합입니다. 오버로드는 a 또는 .을 StreamPipeReader허용합니다.

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 역직렬화되면 공용 setter가 없으므로 Data 속성은 건너뜁집니다. 예외가 throw되지 않습니다.

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파생)은 serialization에 대해 지원됩니다.

역직렬화 지원

사용자 지정 컬렉션은 다음과 같은 경우 역직렬화에 대해 지원됩니다.

알려진 문제

다음 사용자 지정 컬렉션에는 알려진 문제가 있습니다.

알려진 문제에 대한 자세한 내용은 열린 문제를 참조하세요.

지원되는 키 형식

Dictionary 및 SortedList 형식의 키로 사용되는 경우 다음 형식은 기본 제공 지원을 제공합니다.

  • BFloat16(.NET 11 이상)
  • Boolean
  • Byte
  • DateTime
  • DateTimeOffset
  • Decimal
  • Decimal32(.NET 11 이상)
  • Decimal64(.NET 11 이상)
  • Decimal128(.NET 11 이상)
  • Double
  • Enum
  • Guid
  • Int16
  • Int32
  • Int64
  • Object(serialization에만 해당하며 런타임 형식이 이 목록에서 지원되는 형식 중 하나인 경우에만)
  • SByte
  • Single
  • String
  • TimeSpan
  • UInt16
  • UInt32
  • UInt64
  • Uri
  • Version

또한 JsonConverter<T>.WriteAsPropertyName(Utf8JsonWriter, T, JsonSerializerOptions) 및 JsonConverter<T>.ReadAsPropertyName(Utf8JsonReader, Type, JsonSerializerOptions) 메서드를 사용하면 선택한 모든 형식에 대한 사전 키 지원을 추가할 수 있습니다.

BFloat16 및 10진수 부동 소수점 형식

.NET 11부터 , System.Text.Json 및 Decimal128 형식에 대한 Decimal64BFloat16Decimal32기본 제공 변환기가 포함됩니다. 유한 값은 JSON 숫자로 직렬화됩니다.

이러한 형식은 다른 기본 제공 숫자 형식처럼 동작합니다.

JsonMetadataServices 는 원본에서 생성된 메타데이터에 대한 변환기 속성을 노출합니다. 속성은 JsonMetadataServices.BFloat16Converter, JsonMetadataServices.Decimal32Converter, JsonMetadataServices.Decimal64Converter 및 JsonMetadataServices.Decimal128Converter입니다.

F# 차별된 공용 구조체

.NET 11부터 클래스, System.Text.Json 구조체 및 재귀 공용 구조체를 포함하여 F# 차별된 공용 구조체를 직렬화하고 역직렬화합니다.

type Shape =
    | Point
    | Circle of radius: float
  • 필드가 없는 사례는 다음과 같이 대/소문자 이름을 포함하는 JSON 문자열로 "Point"직렬화됩니다.
  • 필드가 있는 사례는 JSON 개체로 직렬화됩니다. 개체에는 판별자 $type 뒤에 사례의 명명된 필드(예: {"$type":"Circle","radius":3.14}.)가 포함됩니다.

JsonSerializerOptions.PropertyNamingPolicy 는 대/소문자 이름 및 필드 이름에 적용됩니다. 대/소문자 수준이 JsonPropertyNameAttribute 우선합니다. 이외의 판별자 속성 이름을 $type사용하려면 .JsonPolymorphicAttribute.TypeDiscriminatorPropertyName

Important

F# 구분된 공용 구조체 지원은 리플렉션 전용입니다. 동적 코드와 시도되지 않은 리플렉션 메타데이터가 필요합니다. 원본 생성 또는 네이티브 AOT에서는 System.Text.Json 사용할 수 없습니다.

지원되지 않는 형식

serialization에는 다음 형식이 지원되지 않습니다.

System.Data 네임스페이스

DataSet 네임스페이스에는 DataTable, System.Data및 관련 형식에 대한 기본 제공 변환기가 없습니다. 보안 지침설명한 대로 신뢰할 수 없는 입력에서 이러한 형식을 역직렬화하는 것은 안전하지 않습니다. 그러나 이러한 형식을 지원하는 사용자 지정 변환기를 작성할 수 있습니다. DataTable직렬화하고 역직렬화하는 샘플 사용자 지정 변환기 코드는 RoundtripDataTable.cs참조하세요.

참고 항목