C#でjsonをシリアライズする技術は、Web API、モバイル、クラウドなど幅広い分野で不可欠です。どのようにオブジェクトをjson文字列に変換し、またjsonをオブジェクトに戻すか知りたい方や、使うライブラリの違いを理解してプロジェクトに最適な選択をしたい方のために、基本から応用まで整理して解説します。最新情報を交えて、実践で役立つ手順や注意点を豊富に紹介します。
目次
C# json シリアライズ の基本とライブラリ選択
C#でjsonシリアライズを行うには、まず「どのライブラリを使うか」を理解することが重要です。一般的には、Microsoftが提供する組み込みライブラリと、機能豊富なサードパーティ製ライブラリの二択になります。それぞれの特徴、利点・欠点、対応する用途を整理します。最新のフレームワークでどちらが推奨されているかも含めて比較します。
System.Text.Json の特徴と使用例
System.Text.Jsonは.NET Core 3.0以降および.NET 5以降に標準搭載されているjson処理ライブラリです。パフォーマンス最適化とメモリ使用の抑制が重視されており、大量データの処理や高速性が要求されるAPIなどで特に有効です。デフォルトでは大文字小文字の区別があり、属性でプロパティ名の制御を行うことが可能です。
またオプションでプロパティ名をcamelCaseにする、null値の扱い、文字列のエスケープ制御など細かな設定ができます。StreamやUtf8JsonWriter/Readerを使うことで、処理中間の文字列生成を抑え、効率的なシリアライズ・デシリアライズが可能です。新しいプロジェクトではまずSystem.Text.Jsonを検討すべきです。
Newtonsoft.Json(Json.NET)の利点と適用シーン
Newtonsoft.Jsonは長年にわたり多くのC#開発者に使われてきたライブラリで、柔軟性と機能豊富さが特徴です。JObject や JToken を使って動的にjsonの構造を操作する機能が充実しており、複雑なデータモデルや不規則なjson構造を扱う際に威力を発揮します。
またデフォルトで大文字小文字を区別しないマッチング、コメント・末尾カンマの許可、様々なカスタム変換コンバーターのサポートなど、標準ライブラリにはない柔軟な挙動が可能です。既存の大規模プロジェクトや複雑なjson操作を必要とするケースでは選択肢として強い優位性があります。
2026年現在の比較:どちらを選ぶべきか
2026年の現状では、新規プロジェクトではSystem.Text.Jsonがデフォルトの選択肢として推奨されるケースが多く、パフォーマンス・NativeAOT対応・ライブラリ依存の少なさなどの点で利点が強調されています。一方でJson.NETは機能の深さや後方互換性、動的処理や例外処理の豊富さで依然として有効です。
以下の表で主要な比較ポイントを整理します。
| 比較項目 | System.Text.Json | Newtonsoft.Json |
| パフォーマンス | 高速でメモリ使用が少ない | 柔軟性はあるが重め |
| 動的/非定型json処理 | 制限あり(JsonNodeなど) | 豊富な動的操作(JObjectなど) |
| 互換性/古い.NET対応 | 最新環境に最適だが古い環境では制約あり | 古いフレームワークにも対応実績が多い |
| 設定の柔軟性 | 属性やオプション設定で制御可能 | より多様なカスタム機能あり |
C# json シリアライズ の基本手順とコード例
実際にオブジェクトをjsonにシリアライズし、jsonからオブジェクトに戻す手順を具体的に示します。基本的なクラス設計、ライブラリの導入、オプション設定、例外処理などを含めて順を追って理解できるようにします。初心者にも応用できる構成です。
オブジェクト定義とアトリビュート設定
まずはC#のクラス(POCO)を設計します。プロパティ名や型をjson構造に合わせます。属性を使用してプロパティの名前をjsonと一致させたり、特定のプロパティを無視するなどの制御ができます。例えば、System.Text.JsonではJsonPropertyName属性を使い、JsonIgnore属性でシリアライズ対象外を指定します。Newtonsoft.JsonでもJsonProperty、JsonIgnoreなど類似した属性があります。
また、null値や既定値の扱い、フィールドの含め方などの設定を属性で細かく制御することで、JSON出力を最適化できます。命名規則(camelCaseやsnake_case)を統一することも可読性と互換性を保つ上で重要です。
シリアライズの基本操作
オブジェクトをjson文字列に変換するにはシンプルなAPI呼び出しが基本です。System.Text.JsonではJsonSerializer.Serialize(object)、Newtonsoft.JsonではJsonConvert.SerializeObject(object)が使用されます。必要に応じてPrettyPrint(インデント付き出力)やnull値除外などのオプションを付与します。
Streamへの出力も可能で、大きなデータを扱うときにはメモリ効率を考慮してStreamベースの操作が有効です。System.Text.JsonではUtf8JsonWriterを使ったストリーミングや先進的なソース生成オプションが提供されています。
デシリアライズと文字列からの復元
json文字列やStreamからC#オブジェクトに変換するデシリアライズの手順も似ています。System.Text.JsonではJsonSerializer.Deserialize(json, options)を使い、Newtonsoft.JsonではJsonConvert.DeserializeObject(json)を使用します。例外処理をして、json形式が不正な場合や型変換に失敗した場合の扱いを設計すべきです。
また、プロパティ名の大文字小文字の違いや欠落プロパティの扱い、配列・ネストされたjsonなどに対応するため、オプションや属性でcase-insensitive設定やAllowTrailingCommasなどの許可設定が利用できます。
C# json シリアライズ の応用:カスタム設定と高度な機能
基本操作が理解できたら、より細かな制御や応用機能を使うことで実務での自由度が上がります。カスタムコンバーター、型ポリモーフィズム、ソース生成、文字のエスケープ、最大深度の制御など、最新環境で提供されている高度な機能を紹介します。
カスタム JsonConverter を使った変換制御
デフォルトのシリアライズ/デシリアライズでは対応できない複雑な型や変換ルールがある場合、カスタム JsonConverter を作成できます。型ごとに変換ロジックを実装して属性またはオプションに登録します。System.Text.Json、Newtonsoft.Jsonそれぞれで作り方は似ていますが、登録順や優先順位、パラメータの扱いに細かい違いがあります。
例えば、日付を特定のフォーマットで出力したり、enumを文字列に変換したりする場合にカスタムコンバーターが必要です。ネストされた型やカスタム型を扱う際の例外処理もここで制御します。
型ポリモーフィズムと派生クラスのシリアライズ
基底クラスを参照として扱いつつ、派生クラスの具体的な型を保持してjsonにシリアライズ/デシリアライズする機能が型ポリモーフィズムです。System.Text.JsonではJsonPolymorphicやJsonDerivedType属性などが利用でき、派生型の判別子を含めて変換できます。Newtonsoft.Jsonも同様の機能がありますが、より柔軟で複雑なケースにも対応します。
ただし、json側に派生型の識別情報がない場合や動的に型を判断する必要がある場合は、追加のロジックや手動設定が必要です。システム全体の整合性を保つ設計が重要です。
設定オプション:命名規則・null値除外・文字エスケープなど
jsonの命名ルール(プロパティ名の命名ポリシー)、null値のどのように扱うか、unicodeやHTML敏感文字のエスケープ方法などは、API設計や外部インターフェースとの互換性に大きな影響を与えます。最新のライブラリでは、これらをオプションで細かく指定可能です。
例として、System.Text.JsonではPropertyNamingPolicy、DefaultIgnoreCondition、EncoderやRead/Writeオプション等があり、Newtonsoft.JsonではNamingStrategy、NullValueHandling、StringEscapeHandlingなどが対応しています。要件に応じて適切に設定することで、不必要な情報の省略やセキュリティ確保が行えます。
ソース生成とパフォーマンス最適化
System.Text.Jsonではソース生成機能が提供されており、コンパイル時にシリアライズ/デシリアライズのコードを生成することでリフレクション使用を減らし、起動時間やメモリ使用量を削減できます。特にNativeAOTやレイテンシに敏感なマイクロサービスで有効です。
また、Utf8JsonWriter/Utf8JsonReaderを活用してストリーミング処理を行う、最大深度を設定してネストが深すぎるjson入力を安全に扱うなどのパフォーマンスおよびセキュリティの工夫が重要です。
よくあるトラブルとその解決策
実際にC#でjsonをシリアライズしていく中で遭遇しやすい問題と、その解決方法を紹介します。型不一致、文字化け、例外による停止などに加え、互換性や既存コードとの衝突などの事例を最新の環境での対処も含めて説明します。
型変換エラーとプロパティ名の不一致
jsonのプロパティ名がC#のプロパティ名と一致しない場合、特にSystem.Text.Jsonでデフォルトの設定のままだとマッチング失敗が起きることがあります。大文字小文字の違い、snake_caseとPascalCaseの違いが原因です。これを解決するにはPropertyNamingPolicyやJsonPropertyName属性、PropertyNameCaseInsensitiveオプションなどを利用します。
また、jsonの値が数値、真偽値、文字列のどれかに固定されていない場合や、null許容型と非null型の不一致がある場合もエラーとなります。nullable型を使う、型変換ロジックを追加するなどの対策が有効です。
大きなjsonとパフォーマンスボトルネック
大容量のjsonを扱うときは、メモリ使用量やGC(ガーベージコレクション)の回数が問題になります。文字列全部を一度に読み込むのではなくStreamを使う、Utf8JsonWriter/Readerやソース生成を使うなどで中間オブジェクトの生成を抑えることが重要です。
また不要なプロパティを除外する、null値を除く設定をするなどjsonサイズを抑える工夫も有効です。APIレスポンスやログなどで転送量・ストレージ使用量を削減できます。
セキュリティ上の注意点
外部から受け取ったjsonをデシリアライズする場合、不正なデータによる攻撃リスクがあります。例えば、無制限のネスト、過剰な文字列長、特殊文字によるクロスサイトスクリプティング(XSS)などです。最大深度の設定やエスケープの制御、コメント・末尾カンマの扱いを厳しくすることが必要です。
また、Newtonsoft.Jsonでは許可されるフォーマットが多いため、その柔軟性が逆にリスクを伴う場合があります。入力検証と例外処理をきちんと設けることが安全性を担保する鍵です。
まとめ
C#でjsonをシリアライズする際の核となるポイントは、まずライブラリの選択とその使用目的をはっきりさせることです。System.Text.Jsonは最新環境での性能と標準組み込みとしてのメリットが大きく、新規開発には第一候補となります。一方でNewtonsoft.Jsonは動的json操作、既存プロジェクトの互換性、複雑な要件への対処に適しています。
基本のシリアライズ/デシリアライズ手順をマスターし、必要であれば命名規則やnull除外、エスケープ制御などのオプション設定、さらにカスタムコンバーターや型ポリモーフィズム、ソース生成などの応用機能を使いこなすと、実務での自在性が高まります。
また、トラブルを未然に防ぐためにモデル設計、例外処理、セキュリティ対策を設けることも不可欠です。適切な選択と正確な実装によって、高性能で安全なjson処理が実現でき、API設計やデータ交換処理の品質を大きく向上させることができます。
コメント