【C#】URLからJSONを取得して直接オブジェクトに変換する方法

目次

概要

Web APIからデータを取得する際、従来の「文字列としてダウンロードしてからJSONデシリアライズを行う」という2段階の手順を、GetFromJsonAsync メソッドを使用することで1ステップに短縮できます。 .NET 5以降で標準化された System.Net.Http.Json を利用し、型安全かつ簡潔に外部データをオブジェクトに取り込みます。

仕様(入出力)

  • 入力: JSONデータを配信しているWeb APIのURL。
  • 出力: JSONデータがマッピングされたC#のインスタンス。コンソールにそのプロパティを表示。
  • 前提: .NET 5.0以上(これ未満の場合は System.Net.Http.Json パッケージが必要)。

基本の使い方

HttpClient の拡張メソッド GetFromJsonAsync<T> を呼び出します。ジェネリック型引数 T には、JSON構造と一致するクラスを指定します。

// Web APIからデータを取得し、Person型に変換する
Person? person = await client.GetFromJsonAsync<Person>("https://api.example.com/users/1");

if (person != null)
{
    Console.WriteLine(person.Name);
}

コード全文

ここでは「通貨レート配信API」から、特定の通貨ペアの情報を取得して表示するコンソールアプリケーションを例示します。

using System;
using System.Net.Http;
using System.Net.Http.Json; // 必須
using System.Text.Json.Serialization;
using System.Threading.Tasks;

class Program
{
    // HttpClientは再利用するためstaticで保持
    private static readonly HttpClient _httpClient = new HttpClient();

    static async Task Main()
    {
        // 架空の為替レートAPIのエンドポイント
        string apiUrl = "https://api.finance-service.net/v1/rates/usd-jpy";

        Console.WriteLine($"データ取得中: {apiUrl} ...");

        try
        {
            // GETリクエストを送り、レスポンスBody(JSON)をExchangeRate型にデシリアライズする
            // 内部で System.Text.Json が使用されます
            ExchangeRate? rateData = await _httpClient.GetFromJsonAsync<ExchangeRate>(apiUrl);

            if (rateData != null)
            {
                Console.WriteLine("--- 取得結果 ---");
                Console.WriteLine($"通貨ペア: {rateData.BaseCurrency} / {rateData.TargetCurrency}");
                Console.WriteLine($"レート  : {rateData.Rate}");
                Console.WriteLine($"更新日時: {rateData.LastUpdated}");
            }
            else
            {
                Console.WriteLine("データはnullでした。");
            }
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"通信エラー: {ex.Message}");
            if (ex.StatusCode.HasValue)
            {
                Console.WriteLine($"ステータスコード: {ex.StatusCode}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"予期せぬエラー: {ex.Message}");
        }
    }
}

// JSONデータに対応するクラス定義
// JSON例: { "base": "USD", "target": "JPY", "current_rate": 145.50, "updated_at": "2026-01-16T10:00:00" }
public class ExchangeRate
{
    // JSONのプロパティ名 "base" を "BaseCurrency" にマッピング
    [JsonPropertyName("base")]
    public string BaseCurrency { get; set; } = string.Empty;

    [JsonPropertyName("target")]
    public string TargetCurrency { get; set; } = string.Empty;

    [JsonPropertyName("current_rate")]
    public decimal Rate { get; set; }

    [JsonPropertyName("updated_at")]
    public DateTime LastUpdated { get; set; }
}

カスタムポイント

  • オプションの指定: GetFromJsonAsync の第2引数に JsonSerializerOptions を渡すことで、キャメルケースの自動変換や、大文字小文字の区別設定などを変更できます。C#var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true // プロパティ名の大文字小文字を区別しない }; var data = await client.GetFromJsonAsync<MyData>(url, options);
  • タイムアウト設定: 通信だけでなくデシリアライズ処理も含めた全体のタイムアウトを制御したい場合は、CancellationToken を渡すオーバーロードを使用してください。

注意点

  1. 例外処理: 通信エラー(404や500など)の場合だけでなく、JSONの形式がクラス定義と一致しない場合(型不一致など)にも JsonException が発生します。堅牢なアプリケーションにするためには、両方の例外を考慮する必要があります。
  2. Null許容: APIが null を返してくる可能性がある場合、戻り値は T?(Null許容型)として受け取るのが安全です。
  3. 文字コード: System.Net.Http.Json はデフォルトで UTF-8 エンコーディングを想定しています。異なるエンコーディングのAPIを扱う場合は、従来通り GetAsync でバイト配列を取得してから変換する必要があります。

応用

JSON配列(リスト)を一括取得する

APIがオブジェクトではなく配列 [...] を返してくる場合は、List<T> や配列型を指定して取得します。

// API戻り値: [{ "id": 1, "name": "A" }, { "id": 2, "name": "B" }]
List<User>? users = await _httpClient.GetFromJsonAsync<List<User>>("https://api.example.com/users");

if (users != null)
{
    foreach (var user in users)
    {
        Console.WriteLine($"ID: {user.Id}, Name: {user.Name}");
    }
}

まとめ

GetFromJsonAsync を活用することで、HTTP通信とJSON解析という頻出パターンを極めてシンプルに記述できます。コードの可読性が向上し、ボイラープレートコード(定型的な記述)を削減できるため、モダンなC#開発においてWeb APIを利用する際の第一選択肢となる手法です。ただし、APIの仕様変更によるJSON構造の不整合が例外を招くリスクがあるため、エラーハンドリングは適切に実装してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次