C#でJSONを扱う方法|読み込み・変換・出力を初心者向けにわかりやすく解説

はじめに

C#でアプリケーションを開発していると、JSONを扱う場面は非常に多くあります。たとえば、Web APIから取得したデータを読み込む、設定ファイルをJSONで管理する、C#のオブジェクトをJSON形式に変換して保存する、といったケースです。

JSONは軽量で読みやすく、多くのプログラミング言語で利用されているデータ形式です。C#でも標準ライブラリや外部ライブラリを使うことで、JSONの読み込み、変換、出力を簡単に行えます。

この記事では、C#でJSONを扱う方法について、初心者にもわかりやすく解説します。JSON文字列の読み込み、C#オブジェクトへの変換、JSONファイルの入出力、よくあるエラーの対処法まで、実践的なコード例を交えて紹介します。

1. C#でJSONを扱う前に知っておきたい基礎知識

1-1. JSONとは何か

JSONは「JavaScript Object Notation」の略で、データをテキスト形式で表現するためのフォーマットです。JavaScriptという名前が入っていますが、現在ではC#、Java、Python、PHPなど、さまざまな言語で利用されています。

JSONは人間が読んでも理解しやすく、プログラムからも扱いやすい形式です。たとえば、ユーザー情報をJSONで表すと次のようになります。

JSON
{
"name": "Taro",
"age": 25,
"email": "taro@example.com"
}

このように、JSONでは「キー」と「値」の組み合わせでデータを表現します。

1-2. C#でJSONを扱う主な場面

C#でJSONを扱う主な場面には、次のようなものがあります。

Web APIから受け取ったJSONデータをC#のオブジェクトに変換する場面は特に多いです。たとえば、天気情報、商品情報、ユーザー情報などをAPIから取得すると、多くの場合JSON形式で返ってきます。

また、アプリケーションの設定ファイルとしてJSONを使うこともあります。接続文字列、画面設定、ログ出力設定などをJSONファイルに保存しておくと、プログラムを変更せずに設定だけを変えられます。

さらに、C#のオブジェクトをJSONに変換してファイルに保存したり、別のシステムへ送信したりするケースもあります。

1-3. JSONの基本構造

JSONには、主に次のようなデータ型があります。

JSON
{
"name": "Hanako",
"age": 30,
"isMember": true,
"skills": ["C#", "SQL", "Azure"],
"address": {
"city": "Tokyo",
"zipCode": "100-0001"
}
}

文字列はダブルクォーテーションで囲みます。数値はそのまま記述できます。真偽値は true または false を使います。複数の値を持つ場合は配列を使い、関連するデータをまとめたい場合はオブジェクトを入れ子にできます。

C#でJSONを扱うときは、このJSONの構造に合わせてクラスを作成することが重要です。

1-4. C#のクラスとJSONの関係

C#でJSONを扱う基本的な考え方は、JSONのキーとC#クラスのプロパティを対応させることです。

たとえば、次のJSONがあるとします。

JSON
{
"name": "Taro",
"age": 25
}

これに対応するC#のクラスは次のように作成できます。

C#
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}

JSONの "name" はC#の Name プロパティに、"age"Age プロパティに対応します。

C#ではプロパティ名をパスカルケースで書くことが一般的ですが、JSONではキャメルケースがよく使われます。そのため、必要に応じてプロパティ名の変換設定を行います。

2. C#でJSONを扱う代表的なライブラリ

2-1. System.Text.Jsonとは

System.Text.Json は、C#でJSONを扱うための標準ライブラリです。現在の.NETでは標準的に利用されており、追加のパッケージをインストールしなくても使えるケースが多いです。

基本的な使い方はシンプルで、JSON文字列をC#オブジェクトに変換する場合は JsonSerializer.Deserialize、C#オブジェクトをJSON文字列に変換する場合は JsonSerializer.Serialize を使います。

C#
using System.Text.Json;

標準ライブラリであるため導入しやすく、パフォーマンス面でも優れています。新しくC#でJSONを扱う場合は、まず System.Text.Json を検討するとよいでしょう。

2-2. Newtonsoft.Jsonとは

Newtonsoft.Json は、長年C#で広く使われてきたJSONライブラリです。別名 Json.NET とも呼ばれます。

利用するにはNuGetからパッケージを追加します。

Bash
dotnet add package Newtonsoft.Json

コードでは次のように使用します。

C#
using Newtonsoft.Json;

Newtonsoft.Json は柔軟な機能が多く、複雑なJSONの変換や古いプロジェクトでよく利用されています。既存のC#プロジェクトでは、今でも Newtonsoft.Json が使われていることがあります。

2-3. System.Text.JsonとNewtonsoft.Jsonの違い

System.Text.Json は.NET標準のJSONライブラリで、軽量かつ高速に動作しやすいことが特徴です。新しいC#プロジェクトでは、まずこちらを使うのが一般的です。

一方、Newtonsoft.Json は歴史が長く、柔軟な設定や豊富な機能を持っています。特に、複雑なJSON変換、動的なJSON操作、既存システムとの互換性が必要な場合に使われることがあります。

簡単なJSONの読み込みや出力であれば、System.Text.Json で十分対応できます。特殊な変換や既存コードとの関係がある場合は、Newtonsoft.Json を選ぶこともあります。

2-4. 初心者はどちらを使うべきか

初心者がC#でJSONを学ぶなら、まずは System.Text.Json から始めるのがおすすめです。標準ライブラリとして使えるため導入が簡単で、基本的なJSONの読み込み、変換、出力を覚えるには十分です。

ただし、学習中に古いサンプルコードを見ると Newtonsoft.Json が使われていることもあります。その場合でも考え方は大きく変わりません。

この記事では、主に System.Text.Json を使ってC#でJSONを扱う方法を解説します。

3. C#でJSON文字列を読み込む方法

3-1. JSON文字列をC#のオブジェクトに変換する

C#でJSON文字列を読み込むには、JSONの構造に対応するクラスを作成し、JsonSerializer.Deserialize を使ってオブジェクトに変換します。

次のようなJSON文字列を考えます。

JSON
{
"name": "Taro",
"age": 25
}

このJSONに対応するクラスを用意します。

C#
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}

JSON文字列をC#のオブジェクトに変換するコードは次のとおりです。

C#
using System;
using System.Text.Json;

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

class Program
{
static void Main()
{
string json = """
{
"name": "Taro",
"age": 25
}
""";

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

User user = JsonSerializer.Deserialize<User>(json, options);

Console.WriteLine(user.Name);
Console.WriteLine(user.Age);
}
}

PropertyNameCaseInsensitive = true を指定すると、JSONのキー名とC#のプロパティ名の大文字・小文字の違いを無視して変換できます。

3-2. JsonSerializer.Deserializeの基本的な使い方

JsonSerializer.Deserialize は、JSON文字列を指定した型に変換するメソッドです。

基本形は次のようになります。

C#
T result = JsonSerializer.Deserialize<T>(json);

たとえば、JSONを User 型に変換する場合は次のように書きます。

C#
User user = JsonSerializer.Deserialize<User>(json);

ただし、JSONのキーが "name"、C#のプロパティが Name のように大文字・小文字が異なる場合、正しく値が入らないことがあります。そのため、初心者のうちは次のオプションを付けると安心です。

C#
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

User user = JsonSerializer.Deserialize<User>(json, options);

これにより、nameName のような違いを吸収できます。

3-3. JSONに対応するクラスを作成する方法

C#でJSONを読み込むときは、JSONの構造に合わせてクラスを作成します。

次のJSONを例にします。

JSON
{
"id": 1,
"title": "C#入門",
"price": 2500
}

対応するC#クラスは次のようになります。

C#
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public int Price { get; set; }
}

JSONのキーとC#のプロパティが対応していれば、次のように変換できます。

C#
string json = """
{
"id": 1,
"title": "C#入門",
"price": 2500
}
""";

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

Book book = JsonSerializer.Deserialize<Book>(json, options);

Console.WriteLine(book.Title);

JSONの構造が複雑になるほど、対応するC#クラスの設計が重要になります。

3-4. 配列形式のJSONを読み込む方法

JSONでは、複数のデータを配列として表現できます。

JSON
[
{
"name": "Taro",
"age": 25
},
{
"name": "Hanako",
"age": 30
}
]

このようなJSONをC#で読み込む場合は、List<T> を使います。

C#
using System;
using System.Collections.Generic;
using System.Text.Json;

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

class Program
{
static void Main()
{
string json = """
[
{
"name": "Taro",
"age": 25
},
{
"name": "Hanako",
"age": 30
}
]
""";

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

List<User> users = JsonSerializer.Deserialize<List<User>>(json, options);

foreach (var user in users)
{
Console.WriteLine($"{user.Name}: {user.Age}");
}
}
}

JSONの先頭が [ で始まる場合は、配列形式のJSONです。この場合、C#側では配列や List<T> として受け取ります。

3-5. ネストされたJSONを読み込む方法

JSONでは、オブジェクトの中にさらにオブジェクトを持つことができます。これをネストされたJSONと呼びます。

JSON
{
"name": "Taro",
"address": {
"city": "Tokyo",
"zipCode": "100-0001"
}
}

このJSONをC#で読み込むには、入れ子構造に合わせてクラスを分けます。

C#
public class User
{
public string Name { get; set; }
public Address Address { get; set; }
}

public class Address
{
public string City { get; set; }
public string ZipCode { get; set; }
}

読み込みコードは次のようになります。

C#
string json = """
{
"name": "Taro",
"address": {
"city": "Tokyo",
"zipCode": "100-0001"
}
}
""";

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

User user = JsonSerializer.Deserialize<User>(json, options);

Console.WriteLine(user.Name);
Console.WriteLine(user.Address.City);

ネストされたJSONでは、JSONの階層に合わせてC#のクラスも階層構造にするのが基本です。

4. C#のオブジェクトをJSONに変換する方法

4-1. C#オブジェクトをJSON文字列に変換する

C#のオブジェクトをJSON文字列に変換することを、シリアライズと呼びます。

たとえば、次のようなC#オブジェクトがあるとします。

C#
var user = new User
{
Name = "Taro",
Age = 25
};

このオブジェクトをJSON文字列に変換するには、JsonSerializer.Serialize を使います。

C#
string json = JsonSerializer.Serialize(user);
Console.WriteLine(json);

出力結果は次のようになります。

JSON
{"Name":"Taro","Age":25}

C#のプロパティ名がそのままJSONのキー名として出力されます。

4-2. JsonSerializer.Serializeの基本的な使い方

JsonSerializer.Serialize の基本形は次のとおりです。

C#
string json = JsonSerializer.Serialize(オブジェクト);

実際のコード例を見てみましょう。

C#
using System;
using System.Text.Json;

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

class Program
{
static void Main()
{
User user = new User
{
Name = "Taro",
Age = 25
};

string json = JsonSerializer.Serialize(user);

Console.WriteLine(json);
}
}

このように、C#のオブジェクトをJSONに変換する処理は非常にシンプルです。

4-3. JSONを見やすく整形して出力する方法

そのままJSONを出力すると、1行で表示されるため読みづらい場合があります。

JSON
{"Name":"Taro","Age":25}

見やすく整形して出力したい場合は、WriteIndented = true を指定します。

C#
var options = new JsonSerializerOptions
{
WriteIndented = true
};

string json = JsonSerializer.Serialize(user, options);

Console.WriteLine(json);

出力結果は次のようになります。

JSON
{
"Name": "Taro",
"Age": 25
}

設定ファイルとしてJSONを保存する場合や、ログとしてJSONを確認したい場合は、整形して出力すると読みやすくなります。

4-4. プロパティ名を変更してJSONに出力する方法

C#ではプロパティ名を Name のようにパスカルケースで書くことが一般的ですが、JSONでは name のようにキャメルケースで出力したいことがあります。

その場合は、PropertyNamingPolicy = JsonNamingPolicy.CamelCase を指定します。

C#
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

string json = JsonSerializer.Serialize(user, options);

Console.WriteLine(json);

出力結果は次のようになります。

JSON
{
"name": "Taro",
"age": 25
}

また、特定のプロパティだけJSONのキー名を変更したい場合は、JsonPropertyName 属性を使います。

C#
using System.Text.Json.Serialization;

public class User
{
[JsonPropertyName("user_name")]
public string Name { get; set; }

public int Age { get; set; }
}

この場合、Name プロパティはJSONでは user_name として出力されます。

4-5. nullや空の値を出力する場合の注意点

C#オブジェクトに null の値がある場合、通常はJSONにも null として出力されます。

C#
var user = new User
{
Name = null,
Age = 25
};

string json = JsonSerializer.Serialize(user);
Console.WriteLine(json);

出力例は次のとおりです。

JSON
{"Name":null,"Age":25}

null のプロパティをJSONに含めたくない場合は、DefaultIgnoreCondition を指定します。

C#
using System.Text.Json.Serialization;

var options = new JsonSerializerOptions
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

string json = JsonSerializer.Serialize(user, options);

ただし、null を出力しない設定にすると、受け取り側で必要な項目が存在しないと判断される可能性があります。API連携では、null として送るべきなのか、項目自体を省略するべきなのかを確認しておくことが大切です。

5. C#でJSONファイルを読み込み・出力する方法

5-1. JSONファイルを読み込む基本手順

C#でJSONファイルを読み込む基本手順は、次のとおりです。

まず、JSONファイルをテキストとして読み込みます。次に、読み込んだJSON文字列を JsonSerializer.Deserialize でC#オブジェクトに変換します。

たとえば、user.json というファイルがあるとします。

JSON
{
"name": "Taro",
"age": 25
}

このファイルを読み込むコードは次のようになります。

C#
string json = File.ReadAllText("user.json");

ファイルを読み込むには、System.IO 名前空間を使います。

C#
using System.IO;

5-2. 読み込んだJSONファイルをオブジェクトに変換する

読み込んだJSON文字列をC#オブジェクトに変換するには、次のようにします。

C#
using System;
using System.IO;
using System.Text.Json;

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

class Program
{
static void Main()
{
string json = File.ReadAllText("user.json");

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

User user = JsonSerializer.Deserialize<User>(json, options);

Console.WriteLine(user.Name);
Console.WriteLine(user.Age);
}
}

JSONファイルを扱う場合も、基本はJSON文字列を扱う場合と同じです。違いは、JSONの取得元が文字列リテラルではなくファイルである点だけです。

5-3. オブジェクトをJSONファイルとして保存する

C#のオブジェクトをJSONファイルとして保存するには、JsonSerializer.Serialize でJSON文字列に変換し、File.WriteAllText でファイルに書き込みます。

C#
using System;
using System.IO;
using System.Text.Json;

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

class Program
{
static void Main()
{
User user = new User
{
Name = "Hanako",
Age = 30
};

var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

string json = JsonSerializer.Serialize(user, options);

File.WriteAllText("user.json", json);

Console.WriteLine("JSONファイルを保存しました。");
}
}

このコードを実行すると、次のようなJSONファイルが作成されます。

JSON
{
"name": "Hanako",
"age": 30
}

5-4. ファイルパス指定時の注意点

JSONファイルを読み込むときに注意したいのが、ファイルパスです。

C#
File.ReadAllText("user.json");

このように相対パスを指定した場合、実行時のカレントディレクトリを基準にファイルが探されます。Visual Studioや.NET CLIで実行している場合、ソースコードのあるフォルダではなく、ビルド後の出力フォルダが基準になることがあります。

確実に場所を指定したい場合は、絶対パスを使うか、アプリケーションの実行フォルダを基準にパスを組み立てます。

C#
string path = Path.Combine(AppContext.BaseDirectory, "user.json");
string json = File.ReadAllText(path);

ファイルが見つからないエラーが出る場合は、まず実際にどのフォルダを参照しているか確認しましょう。

5-5. 文字コードや改行で起きやすいトラブル

JSONファイルに日本語が含まれる場合、文字コードに注意が必要です。基本的にはUTF-8で保存しておくのが安全です。

C#でUTF-8を指定して読み書きする場合は、次のように書けます。

C#
using System.Text;

string json = File.ReadAllText("user.json", Encoding.UTF8);
File.WriteAllText("user.json", json, Encoding.UTF8);

また、JSONでは文字列の中に改行やダブルクォーテーションを含める場合、エスケープが必要です。

JSON
{
"message": "こんにちは\nC#でJSONを扱います"
}

JSONの形式が崩れると読み込み時にエラーになるため、手作業でJSONファイルを編集する場合は、カンマの付け忘れやダブルクォーテーションの不足にも注意しましょう。

6. C#でJSONを扱う実践例

6-1. APIレスポンスのJSONをC#で読み込む

C#でJSONを扱う代表的な実践例が、Web APIのレスポンスを読み込む処理です。

APIからJSONを取得するには、HttpClient を使います。

C#
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}

class Program
{
static async Task Main()
{
using HttpClient client = new HttpClient();

string url = "https://example.com/api/users/1";
string json = await client.GetStringAsync(url);

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

User user = JsonSerializer.Deserialize<User>(json, options);

Console.WriteLine(user.Name);
Console.WriteLine(user.Email);
}
}

実際のAPIでは、レスポンスのJSON構造に合わせてC#のクラスを作成します。API仕様書がある場合は、どのキーがどの型で返ってくるのか確認しておきましょう。

6-2. 設定ファイルとしてJSONを使う

JSONは設定ファイルとしてもよく使われます。

たとえば、次のような appsettings.json を用意します。

JSON
{
"appName": "SampleApp",
"maxRetryCount": 3,
"enableLog": true
}

対応するC#クラスを作成します。

C#
public class AppSettings
{
public string AppName { get; set; }
public int MaxRetryCount { get; set; }
public bool EnableLog { get; set; }
}

読み込み処理は次のようになります。

C#
string json = File.ReadAllText("appsettings.json");

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

AppSettings settings = JsonSerializer.Deserialize<AppSettings>(json, options);

Console.WriteLine(settings.AppName);
Console.WriteLine(settings.MaxRetryCount);
Console.WriteLine(settings.EnableLog);

設定ファイルとしてJSONを使うと、プログラムの再ビルドをしなくても設定を変更できるため便利です。

6-3. ListやDictionaryをJSONに変換する

C#の ListDictionary もJSONに変換できます。

List<T> をJSONに変換する例です。

C#
var users = new List<User>
{
new User { Name = "Taro", Age = 25 },
new User { Name = "Hanako", Age = 30 }
};

var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

string json = JsonSerializer.Serialize(users, options);

Console.WriteLine(json);

出力結果は配列形式のJSONになります。

JSON
[
{
"name": "Taro",
"age": 25
},
{
"name": "Hanako",
"age": 30
}
]

Dictionary をJSONに変換する例も見てみましょう。

C#
var scores = new Dictionary<string, int>
{
{ "math", 90 },
{ "english", 85 },
{ "science", 88 }
};

string json = JsonSerializer.Serialize(scores, new JsonSerializerOptions
{
WriteIndented = true
});

Console.WriteLine(json);

出力結果は次のようになります。

JSON
{
"math": 90,
"english": 85,
"science": 88
}

キーと値の組み合わせをそのままJSONにしたい場合は、Dictionary が便利です。

6-4. JSONの一部の値だけを取得する

JSON全体をクラスに変換せず、一部の値だけを取得したい場合は、JsonDocument を使う方法があります。

C#
using System;
using System.Text.Json;

string json = """
{
"name": "Taro",
"age": 25,
"email": "taro@example.com"
}
""";

using JsonDocument document = JsonDocument.Parse(json);

JsonElement root = document.RootElement;

string name = root.GetProperty("name").GetString();
int age = root.GetProperty("age").GetInt32();

Console.WriteLine(name);
Console.WriteLine(age);

JsonDocument を使うと、クラスを作成せずにJSONの中身を直接参照できます。

ただし、キーが存在しない場合に例外が発生することがあります。安全に取得したい場合は、TryGetProperty を使います。

C#
if (root.TryGetProperty("email", out JsonElement emailElement))
{
string email = emailElement.GetString();
Console.WriteLine(email);
}

JSONの構造が決まっている場合はクラスに変換する方法、必要な値だけ取得したい場合は JsonDocument を使う方法が便利です。

6-5. 型が決まっていないJSONを扱う方法

JSONの構造が固定されていない場合や、キーが実行時までわからない場合は、Dictionary<string, object>JsonElement を使うことがあります。

たとえば、次のようなJSONを扱います。

JSON
{
"name": "Taro",
"age": 25,
"isMember": true
}

Dictionary<string, JsonElement> として読み込む例です。

C#
string json = """
{
"name": "Taro",
"age": 25,
"isMember": true
}
""";

var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);

foreach (var item in data)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}

値の型に応じて処理を分けたい場合は、ValueKind を確認します。

C#
foreach (var item in data)
{
switch (item.Value.ValueKind)
{
case JsonValueKind.String:
Console.WriteLine(item.Value.GetString());
break;

case JsonValueKind.Number:
Console.WriteLine(item.Value.GetInt32());
break;

case JsonValueKind.True:
case JsonValueKind.False:
Console.WriteLine(item.Value.GetBoolean());
break;
}
}

型が決まっていないJSONは柔軟に扱えますが、コードが複雑になりやすいです。可能であれば、JSONの形式を決めてクラスに変換する方が保守しやすくなります。

7. C#でJSONを扱うときによくあるエラーと対処法

7-1. JSONの形式が不正な場合のエラー

JSONの形式が正しくない場合、読み込み時に例外が発生します。

たとえば、次のJSONは不正です。

JSON
{
"name": "Taro",
"age": 25,
}

最後の項目の後に余分なカンマがあります。JSONでは、最後の要素の後にカンマを付けることはできません。

C#で読み込むと、JsonException が発生する可能性があります。

C#
try
{
User user = JsonSerializer.Deserialize<User>(json);
}
catch (JsonException ex)
{
Console.WriteLine("JSONの形式が不正です。");
Console.WriteLine(ex.Message);
}

JSONの読み込み処理では、例外処理を入れておくと安全です。

7-2. クラスのプロパティ名とJSONのキー名が一致しない場合

JSONのキー名とC#のプロパティ名が一致しない場合、値が正しく設定されないことがあります。

JSON
{
"user_name": "Taro"
}

C#のクラスが次のようになっていると、Name に値が入らない場合があります。

C#
public class User
{
public string Name { get; set; }
}

このような場合は、JsonPropertyName を使って対応します。

C#
using System.Text.Json.Serialization;

public class User
{
[JsonPropertyName("user_name")]
public string Name { get; set; }
}

また、単に大文字・小文字の違いだけであれば、PropertyNameCaseInsensitive = true で対応できます。

C#
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

7-3. 日付や数値の変換で失敗する場合

JSONの値とC#の型が合っていない場合、変換に失敗することがあります。

たとえば、C#側では int を期待しているのに、JSONでは文字列になっているケースです。

JSON
{
"age": "25"
}

C#クラスが次のようになっている場合、変換時にエラーになることがあります。

C#
public class User
{
public int Age { get; set; }
}

JSON側で数値として扱うなら、次のようにダブルクォーテーションを外すのが基本です。

JSON
{
"age": 25
}

日付の場合も、C#の DateTime に変換できる形式である必要があります。

JSON
{
"createdAt": "2026-01-01T10:00:00"
}

C#クラスは次のようになります。

C#
public class Item
{
public DateTime CreatedAt { get; set; }
}

APIや外部システムと連携する場合は、日付形式や数値形式がC#側の型と一致しているか確認しましょう。

7-4. null参照でエラーになる場合

JSONの中に値が存在しない、または null が含まれている場合、C#側でnull参照エラーが発生することがあります。

JSON
{
"name": null
}

次のようなコードでは、Namenull の場合にエラーになる可能性があります。

C#
Console.WriteLine(user.Name.Length);

安全に処理するには、nullチェックを行います。

C#
if (user.Name != null)
{
Console.WriteLine(user.Name.Length);
}

または、null条件演算子を使います。

C#
Console.WriteLine(user.Name?.Length);

C#でJSONを扱うときは、JSONに必ず値が入っているとは限らないと考えて実装することが大切です。

7-5. 日本語が文字化けする場合

JSONファイル内の日本語が文字化けする場合は、文字コードが原因であることが多いです。基本的にはJSONファイルをUTF-8で保存し、C#側でもUTF-8として読み書きします。

C#
using System.Text;

string json = File.ReadAllText("data.json", Encoding.UTF8);

保存時もUTF-8を指定できます。

C#
File.WriteAllText("data.json", json, Encoding.UTF8);

また、JSONを出力したときに日本語が \u3053\u3093\u306b\u3061\u306f のようにエスケープされることがあります。これは文字化けではなく、Unicodeエスケープです。

日本語をそのまま出力したい場合は、エンコーダーの設定を変更できます。

C#
using System.Text.Encodings.Web;
using System.Text.Json;

var options = new JsonSerializerOptions
{
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

string json = JsonSerializer.Serialize(user, options);

ただし、HTMLに埋め込むJSONなどではセキュリティ上の注意が必要です。用途に応じて設定しましょう。

8. C#でJSONを扱うときの注意点

8-1. JSONとC#の型の違いを理解する

JSONとC#では、扱える型の考え方が異なります。

JSONには、文字列、数値、真偽値、配列、オブジェクト、nullといった基本的な型があります。一方、C#には intdoubledecimalDateTimeboolstringList<T>、独自クラスなど、より細かい型があります。

そのため、JSONをC#に変換するときは、どのJSONの値をどのC#の型に対応させるかを意識する必要があります。

たとえば、金額を扱う場合は int でよいのか、decimal が適切なのかを考える必要があります。日付を扱う場合も、文字列として持つのか、DateTime に変換するのかを決めておくとよいでしょう。

8-2. 例外処理を入れて安全に読み込む

JSONは外部ファイルやAPIから取得することが多いため、必ず正しい形式であるとは限りません。ファイルが存在しない、JSONの形式が壊れている、想定外の値が入っているといったケースがあります。

そのため、JSONの読み込み処理には例外処理を入れておくのがおすすめです。

C#
try
{
string json = File.ReadAllText("user.json");

var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

User user = JsonSerializer.Deserialize<User>(json, options);

Console.WriteLine(user.Name);
}
catch (FileNotFoundException)
{
Console.WriteLine("JSONファイルが見つかりません。");
}
catch (JsonException)
{
Console.WriteLine("JSONの形式が不正です。");
}
catch (Exception ex)
{
Console.WriteLine("予期しないエラーが発生しました。");
Console.WriteLine(ex.Message);
}

特に外部から受け取るJSONを処理する場合は、エラーが起きる前提で実装しましょう。

8-3. 大きなJSONファイルを扱う場合の注意点

小さなJSONファイルであれば、File.ReadAllText で全体を読み込んでも問題になりにくいです。しかし、大きなJSONファイルを扱う場合は、メモリ使用量に注意が必要です。

巨大なJSONを一度に文字列として読み込むと、メモリを多く消費します。大量データを扱う場合は、ストリームを使った読み込みや、必要な部分だけを処理する方法を検討しましょう。

また、JSONの配列が非常に大きい場合は、全件を List<T> に変換するとメモリ負荷が高くなることがあります。処理対象のデータ量が多い場合は、設計段階で読み込み方法を考えておくことが重要です。

8-4. セキュリティ面で気をつけること

JSONは外部から受け取ることが多いため、セキュリティ面にも注意が必要です。

APIから受け取ったJSONやユーザーがアップロードしたJSONファイルは、信頼できるとは限りません。想定外の値、極端に大きなデータ、不正な形式のデータが含まれる可能性があります。

そのため、JSONを読み込んだ後は、必要に応じて値の検証を行いましょう。

C#
if (user.Age < 0 || user.Age > 150)
{
Console.WriteLine("年齢の値が不正です。");
}

また、JSONに含まれる文字列をそのままSQLに埋め込んだり、HTMLに出力したりするのは危険です。SQLインジェクションやクロスサイトスクリプティングなどのリスクを避けるため、適切なエスケープやパラメータ化を行いましょう。

8-5. 可読性の高いクラス設計を意識する

C#でJSONを扱うときは、JSONの構造に合わせてクラスを作成することが多いです。このとき、単に変換できればよいというだけでなく、読みやすく保守しやすいクラス設計を意識しましょう。

たとえば、ネストされたJSONをすべて1つのクラスに詰め込むのではなく、意味のある単位でクラスを分けると理解しやすくなります。

C#
public class Order
{
public int Id { get; set; }
public Customer Customer { get; set; }
public List<OrderItem> Items { get; set; }
}

public class Customer
{
public string Name { get; set; }
public string Email { get; set; }
}

public class OrderItem
{
public string ProductName { get; set; }
public int Quantity { get; set; }
}

このように、JSONの構造と業務上の意味を対応させてクラスを設計すると、後からコードを読んだときにも理解しやすくなります。

まとめ

C#でJSONを扱うには、主に System.Text.Json を使います。JSON文字列をC#のオブジェクトに変換する場合は JsonSerializer.Deserialize、C#のオブジェクトをJSON文字列に変換する場合は JsonSerializer.Serialize を使うのが基本です。

JSONを読み込むときは、JSONの構造に対応するC#クラスを作成することが重要です。配列形式のJSONは List<T>、ネストされたJSONは入れ子のクラスで表現できます。JSONファイルを扱う場合は、File.ReadAllTextFile.WriteAllText と組み合わせることで、読み込みや保存ができます。

また、C#でJSONを扱う際には、プロパティ名の違い、null、日付や数値の型、文字コード、ファイルパスなどでエラーが起きやすいため注意が必要です。外部から受け取るJSONは必ず正しいとは限らないため、例外処理や値の検証を入れて安全に処理しましょう。

C# JSONの基本を理解しておけば、API連携、設定ファイルの管理、データ保存など、さまざまな場面で応用できます。まずは簡単なJSON文字列の読み込みと出力から試し、少しずつ配列、ネスト、ファイル操作、実践的なAPI連携へ進めていくと理解しやすくなります。