C# System.Text.Json 소개 및 기본 사용법

C# System.Text.Json 소개와 기본 사용법에 대한 포괄적인 안내로 C# 개발자에게 가치 있는 정보를 제공합니다. 지금 읽어보세요!

System.Text.Json은 JSON과 작업하기 위한 고성능, 낮은 할당, 표준 준수 도구를 제공하는 네임스페이스입니다. 이 클래스들은 객체를 JSON 텍스트로 직렬화하고 JSON 텍스트를 객체로 역직렬화하는 데 사용됩니다. UTF-8 지원도 내장되어 있어서 효율적으로 작업할 수 있습니다. JSON 데이터를 효과적으로 처리하고.NET 개발에서 필수적인 기능을 제공합니다.

JSON parse

System.Text.Json에서 제공하는 JsonDocument 클래스를 활용하면 JSON 데이터를 쉽게 탐색하고 조작할 수 있습니다. 이를 통해 데이터를 읽고 쓰는 작업을 보다 효율적으로 수행할 수 있습니다. JsonDocument를 이용하여 JSON 데이터를 효과적으로 관리하는 방법을 익혀봅시다.

using System.Text.Json;

string data = @" [ {""name"": ""영희"", ""occupation"": ""원예가""}, 
    {""name"": ""철수"", ""occupation"": ""운전사""} ]"; 

using JsonDocument doc = JsonDocument.Parse(data);
JsonElement root = doc.RootElement;

Console.WriteLine(root);

var u1 = root[0];
var u2 = root[1];
Console.WriteLine(u1); // 첫 번째 요소 출력
Console.WriteLine(u2); // 두 번째 요소 출력

Console.WriteLine(u1.GetProperty("name")); // 첫 번째 요소의 'name' 속성 출력
Console.WriteLine(u1.GetProperty("occupation")); // 첫 번째 요소의 'occupation' 속성 출력

Console.WriteLine(u2.GetProperty("name")); // 두 번째 요소의 'name' 속성 출력
Console.WriteLine(u2.GetProperty("occupation")); // 두 번째 요소의 'occupation' 속성 출력

JsonDocument.Parse는 UTF-8로 인코딩된 데이터를 단일 JSON 값으로 파싱하는 메서드입니다. 이를 사용하여 JSON 데이터를 JsonDocument로 파싱하고, 이후 해당 데이터를 적절히 처리하고 조작할 수 있습니다.

using JsonDocument doc = JsonDocument.Parse(data);

위 코드는 JSON 문자열을 JsonDocument로 파싱합니다.

JsonElement root = doc.RootElement;

var u1 = root[0];
var u2 = root[1];

루트 엘리먼트에 대한 참조를 가져옵니다.
연산자를 사용하여 JSON 문서의 첫 번째와 두 번째 하위 요소를 가져옵니다.

u1.GetProperty("name");
u1.GetProperty("occupation"));

GetProperty을 사용 하여 요소의 속성을 가져옵니다.

위 예제에 대한 결과 값은 다음과 같습니다.

[ {"name": "영희", "occupation": "원예가"},
    {"name": "철수", "occupation": "운전사"} ]
{"name": "영희", "occupation": "원예가"}
{"name": "철수", "occupation": "운전사"}
영희
원예가
철수
운전사

JSON enumerate

다음은 JSON 데이터를 열거하는 방법입니다. 이 방법을 사용하면 JSON 데이터를 C# 객체로 변환할 필요 없이도 배열을 읽고 처리할 수 있습니다.

using System.Text.Json;

string data = @" [ {""name"": ""영희"", ""occupation"": ""원예가""}, 
    {""name"": ""철수"", ""occupation"": ""운전사""} ]";

using var doc = JsonDocument.Parse(data);
JsonElement root = doc.RootElement;

var users = root.EnumerateArray();

while (users.MoveNext())
{
    var user = users.Current;
    System.Console.WriteLine(user);

    var props = user.EnumerateObject();

    while (props.MoveNext())
    {
        var prop = props.Current;
        Console.WriteLine($"{prop.Name}: {prop.Value}");
    }
}

이 예시에서는 루트 요소의 내용을 열거합니다.

var users = root.EnumerateArray();

하위 요소의 배열을 가져옵니다.

while (users.MoveNext())
{
    var user = users.Current;
    Console.WriteLine(user);
    // ...
}

while 루프를 사용하여 요소의 배열을 확인합니다.

var props = user.EnumerateObject();

while (props.MoveNext())
{
    var prop = props.Current;
    Console.WriteLine($"{prop.Name}: {prop.Value}");
}

두 번째 while 루프에서는 각 요소의 속성을 확인합니다.

출력값은 다음과 같습니다.

{"name": "영희", "occupation": "원예가"}
name: 영희
occupation: 원예가
{"name": "철수", "occupation": "운전사"}
name: 철수
occupation: 운전사

직렬화 및 역직렬화

직렬화 (Serialization)

class HaroStudio
{
    public string Name { get; set; }
    public string Description { get; set; }
}
// HaroStudio 객체 생성
HaroStudio bsObj = new HaroStudio()
{
    Name = "Haro",
    Description = "Admin"
};

// HaroStudio 객체를 JSON 문자열로 변환
string jsonData = JsonSerializer.Serialize(bsObj);

역직렬화 (Deserialization)

string json = @"{
  'Name': 'Haro',
  'Description': 'Admin'
}";

HaroStudio bsObj = JsonSerializer.Deserialize<HaroStudio>(json);

직렬화 및 역직렬화는 위와 같이 사용하면 쉽게 직렬화 및 역직렬화가 가능합니다.

JsonSerializerOptions

JsonSerializerOptions은 C#에서 JSON 직렬화 및 역직렬화 작업을 세부적으로 제어하는 데 사용됩니다.

예를 들어, JsonSerializerOptions를 사용하여 속성 이름의 대/소문자 구분 여부, 누락된 속성 처리 방법 등을 설정할 수 있습니다.

using System;
using System.Text.Json;

class Program
{
    static void Main()
    {
        // JsonSerializerOptions 생성
        var options = new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true, // 대/소문자 구분 없이 속성 이름 매칭
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase // 카멜케이스 형태로 속성 이름 변환
        };

        // 객체를 JSON 문자열로 직렬화
        var person = new Person { Name = "John", Age = 30 };
        string json = JsonSerializer.Serialize(person, options);
        Console.WriteLine(json);

        // JSON 문자열을 객체로 역직렬화
        string jsonString = "{\"name\": \"Alice\", \"age\": 25}";
        var personDeserialized = JsonSerializer.Deserialize<Person>(jsonString, options);
        Console.WriteLine($"Name: {personDeserialized.Name}, Age: {personDeserialized.Age}");
    }
}

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

위 코드에서 JsonSerializerOptions를 사용하여 JSON 직렬화 및 역직렬화 작업의 설정을 조정했어요. 이 옵션들을 조정하면 원하는 대로 JSON 데이터를 다룰 수 있습니다.

출력은 다음과 같습니다.

{"name":"John","age":30}
Name: Alice, Age: 25

Utf8JsonWriter

Utf8JsonWriter는 C#에서 사용되는 고성능의 JSON 작성기입니다. 메모리를 효율적으로 사용하면서도 JSON 데이터를 생성할 수 있도록 도와줍니다. StringInt32 및 DateTime과 같은 일반적인 .NET 형식에서 UTF-8 인코딩된 JSON 텍스트를 쓸 수 있는 고성능 방법입니다.

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

class Program
{
    static void Main()
    {
        // 메모리 스트림을 생성하여 Utf8JsonWriter에 연결
        using var stream = new MemoryStream();
        using (var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }))
        {
            // JSON 객체 시작
            writer.WriteStartObject();

            writer.WritePropertyName("name");
            writer.WriteStringValue("John");

            writer.WritePropertyName("age");
            writer.WriteNumberValue(30);

            writer.WriteEndObject(); // JSON 객체 끝
        }

        // 생성된 JSON 데이터 출력
        string jsonString = Encoding.UTF8.GetString(stream.ToArray());
        Console.WriteLine(jsonString);
    }
}

이 코드는 Utf8JsonWriter를 사용하여 JSON 객체를 생성하고, 그 결과를 문자열로 변환하여 출력합니다. Utf8JsonWriter를 사용하면 메모리를 효율적으로 활용하면서도 JSON 데이터를 생성할 수 있습니다.

출력물은 다음과 같습니다.

{
  "name": "John",
  "age": 30
}

Utf8JsonReader

Utf8JsonReader는 C#에서 사용되는 JSON 파서로, System.Text.Json 네임스페이스에 속해 있습니다. 이것은 메모리를 효율적으로 사용하면서 JSON 데이터를 읽을 수 있도록 도와줍니다.

아래는 Utf8JsonReader를 사용하여 JSON 데이터를 읽는 간단한 예제입니다.

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

class Program
{
    static void Main()
    {
        string jsonString = "{\"name\": \"John\", \"age\": 30}";

        // JSON 문자열을 UTF-8 바이트 배열로 변환
        byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString);

        // UTF-8 바이트 배열로 Utf8JsonReader 생성
        var reader = new Utf8JsonReader(jsonBytes);

        // JSON 데이터 읽기
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.PropertyName)
            {
                string? propertyName = reader.GetString();
                reader.Read();

                switch (reader.TokenType)
                {
                    case JsonTokenType.String:
                        {
                            Console.WriteLine($"{propertyName}: {reader.GetString()}");
                            break;
                        }

                    case JsonTokenType.Number:
                        {
                            Console.WriteLine($"{propertyName}: {reader.GetInt32()}");
                            break;
                        }

                        // Other token types elided for brevity
                }
            }
        }
    }
}

이 코드는 Utf8JsonReader를 사용하여 JSON 데이터를 읽고, 각 속성과 해당 값을 출력합니다. Utf8JsonReader를 사용하면 메모리를 효율적으로 활용하면서도 JSON 데이터를 읽을 수 있습니다.

위 사항의 출력물은 다음과 같습니다.

name: John
age: 30

JSON parse async

다음은 C#에서 비동기적으로 JSON을 파싱하는 방법입니다.

using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        string jsonString = "{\"name\": \"John\", \"age\": 30}";

        // JSON 문자열을 MemoryStream으로 변환
        using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));

        // 비동기적으로 JSON 데이터 파싱
        var jsonDocument = await JsonDocument.ParseAsync(memoryStream);

        // JSON 데이터 읽기
        foreach (JsonProperty property in jsonDocument.RootElement.EnumerateObject())
        {
            Console.WriteLine($"{property.Name}: {property.Value}");
        }
    }
}

여기서 JToken.Parse 메서드를 사용하여 JSON 데이터를 비동기적으로 파싱하고, JToken을 사용하여 데이터를 읽고 처리합니다.

결론

System.Text.Json 의 여러 기능들을 짧게 다뤄 보았습니다. System.Text.Json 는 내부적으로 더많은 여러 가지 기능들이 있습니다.

관련글

Leave a Comment