.NET での JSON のシリアル化と逆シリアル化 (マーシャリングとマーシャリング解除) - 概要

System.Text.Json 名前空間は、JavaScript Object Notation (JSON) との間でのシリアル化と逆シリアル化の機能を提供します。 "シリアル化" は、オブジェクトの状態 (つまり、そのプロパティの値) を格納または送信できる形式に変換するプロセスです。 シリアル化された形式には、オブジェクトに関連付けられているメソッドに関する情報は含まれません。 "逆シリアル化" では、シリアル化された形式からオブジェクトを再構築します。

System.Text.Json ライブラリの設計では、ハイ パフォーマンスと、高度な豊富なセットに対する少ないメモリ割り当てが強調されています。 組み込みの UTF-8 サポートによって、UTF-8 としてエンコードされた JSON テキストの読み取りと書き込みのプロセスが最適化されます。これは、web 上のデータおよびディスク上のファイルのための最も一般的なエンコードです。

ライブラリには、メモリ内のドキュメント オブジェクト モデル (DOM) を操作するためのクラスも用意されています。 この機能により、JSON ファイルまたは文字列内の要素へのランダム アクセスが可能になります。

Visual Basic の場合、使用できるライブラリの部分には制限がいくつかあります。 詳細については、「Visual Basic のサポート」をご覧ください。

ライブラリの入手方法

ライブラリは、.NET Core 3.0 以降のバージョン用の共有フレームワークの一部として組み込まれています。 ソース生成機能は、.NET 6 以降のバージョン用の共有フレームワークの一部として組み込まれています。

.NET Core 3.0 より前のバージョンのフレームワークでは、System.Text.Json NuGet パッケージをインストールします。 このパッケージで以下がサポートされます。

  • .NET Standard 2.0 以降
  • .NET Framework 4.6.2 以降
  • .NET Core 2.1 以降
  • .NET 5 以降

名前空間と API

  • System.Text.Json 名前空間には、すべてのエントリ ポイントと主要な型が含まれています。
  • System.Text.Json.Serialization 名前空間には、シリアル化と逆シリアル化に固有の高度なシナリオとカスタマイズのための属性と API が含まれています。

この記事に示されているコード例では、次のいずれかまたは両方の名前空間に using ディレクティブが必要です。

重要

System.Text.Json では、以前に使用した可能性のある次のシリアル化 API はサポートされていません。

HttpClient と HttpContent の拡張メソッド

ネットワークからの JSON ペイロードのシリアル化と逆シリアル化は、一般的な操作です。 HttpClient および HttpContent の拡張メソッドを使用すると、これらの操作を 1 行のコードで実行できます。 これらの拡張メソッドにおいては、JsonSerializerOptions の Web の既定値が使用されます。

次の例では、HttpClientJsonExtensions.GetFromJsonAsyncHttpClientJsonExtensions.PostAsJsonAsync の使用方法を示します。

using System.Net.Http.Json;

namespace HttpClientExtensionMethods
{
    public class User
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Username { get; set; }
        public string? Email { get; set; }
    }

    public class Program
    {
        public static async Task Main()
        {
            using HttpClient client = new()
            {
                BaseAddress = new Uri("https://jsonplaceholder.typicode.com")
            };

            // Get the user information.
            User? user = await client.GetFromJsonAsync<User>("users/1");
            Console.WriteLine($"Id: {user?.Id}");
            Console.WriteLine($"Name: {user?.Name}");
            Console.WriteLine($"Username: {user?.Username}");
            Console.WriteLine($"Email: {user?.Email}");

            // Post a new user.
            HttpResponseMessage response = await client.PostAsJsonAsync("users", user);
            Console.WriteLine(
                $"{(response.IsSuccessStatusCode ? "Success" : "Error")} - {response.StatusCode}");
        }
    }
}

// Produces output like the following example but with different names:
//
//Id: 1
//Name: Tyler King
//Username: Tyler
//Email: Tyler @contoso.com
//Success - Created
Imports System.Net.Http
Imports System.Net.Http.Json

Namespace HttpClientExtensionMethods

    Public Class User
        Public Property Id As Integer
        Public Property Name As String
        Public Property Username As String
        Public Property Email As String
    End Class

    Public Class Program

        Public Shared Async Function Main() As Task
            Using client As New HttpClient With {
                .BaseAddress = New Uri("https://jsonplaceholder.typicode.com")
                }

                ' Get the user information.
                Dim user1 As User = Await client.GetFromJsonAsync(Of User)("users/1")
                Console.WriteLine($"Id: {user1.Id}")
                Console.WriteLine($"Name: {user1.Name}")
                Console.WriteLine($"Username: {user1.Username}")
                Console.WriteLine($"Email: {user1.Email}")

                ' Post a new user.
                Dim response As HttpResponseMessage = Await client.PostAsJsonAsync("users", user1)
                Console.WriteLine(
                $"{(If(response.IsSuccessStatusCode, "Success", "Error"))} - {response.StatusCode}")
            End Using
        End Function

    End Class

End Namespace

' Produces output like the following example but with different names:
'
'Id: 1
'Name: Tyler King
'Username: Tyler
'Email: Tyler @contoso.com
'Success - Created

System.Text.Json には System.Text.Json 用の拡張メソッドもあります。

リフレクションとソース生成

既定では、System.Text.Json ではリフレクションを使用して、実行時にシリアル化と逆シリアル化のためにオブジェクトのプロパティにアクセスする目的で必要なメタデータを収集します。 別の方法として、System.Text.Json では、C# のソース生成機能を使用して、パフォーマンスを向上させ、プライベート メモリの使用量を削減し、アセンブリのトリミングを容易にすることができます。これにより、アプリのサイズが小さくなります。

詳細については、「リフレクションとソース生成」を参照してください。

セキュリティ情報

JsonSerializer の設計時に考慮されたセキュリティ上の脅威と、その脅威を軽減する方法については、「System.Text.Json 脅威モデル」を参照してください。

スレッド セーフ

System.Text.Json シリアライザーは、スレッド セーフを考慮して設計されています。 実際には、これは、ロックされると JsonSerializerOptions インスタンスを複数のスレッド間で安全に共有できることを意味します。 JsonDocument は、JSON 値に対して不変の、そして .NET 8 以降のバージョンではスレッド セーフな DOM 表現を提供します。

その他のリソース