【C#】HttpClientでHTTPステータスコードを判定して分岐処理する方法

目次

概要

HttpClient を使用してWebリクエストを送信した際、通信自体は成功しても、サーバー側で「ページが見つからない(404)」や「内部エラー(500)」が発生している場合があります。

HttpResponseMessage.StatusCode プロパティを確認することで、サーバーからの応答結果に応じた適切な分岐処理(成功時のデータ読み込み、失敗時のログ出力など)を実装します。

仕様(入出力)

  • 入力: アクセス先のURL。
  • 出力: HTTPステータスコード(数値および名前)と、判定結果に応じた処理メッセージ。
  • 前提: .NET標準ライブラリ(System.Net.Http)を使用。

基本の使い方

GetAsync 等の戻り値である HttpResponseMessage オブジェクトから StatusCode プロパティを参照し、HttpStatusCode 列挙型と比較します。

HttpResponseMessage response = await client.GetAsync(url);

// 200 OK かどうかを判定
if (response.StatusCode == HttpStatusCode.OK)
{
    // 成功時の処理
}
// 404 Not Found かどうかを判定
else if (response.StatusCode == HttpStatusCode.NotFound)
{
    // エラー処理
}

コード全文

ここでは、異なるステータスコード(正常、404エラー、その他エラー)をシミュレーションし、それぞれの状況に合わせてコンソール出力を切り替える実装例です。

using System;
using System.Net; // HttpStatusCodeを使うために必要
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    private static readonly HttpClient _client = new HttpClient();

    static async Task Main()
    {
        // 1. 正常なURLへのアクセス (200 OK)
        await CheckUrlAsync("http://httpbin.org/status/200");

        Console.WriteLine();

        // 2. 存在しないURLへのアクセス (404 Not Found)
        await CheckUrlAsync("http://httpbin.org/status/404");

        Console.WriteLine();

        // 3. サーバーエラーが発生するURLへのアクセス (503 Service Unavailable)
        await CheckUrlAsync("http://httpbin.org/status/503");
    }

    static async Task CheckUrlAsync(string url)
    {
        Console.WriteLine($"アクセス中: {url} ...");

        try
        {
            // GetAsyncは、404や500が返ってきても例外を投げず、responseを返します
            using var response = await _client.GetAsync(url);

            // ステータスコードの表示
            // (int)キャストすると数値(例: 200)、そのまま出力すると列挙型名(例: OK)になります
            Console.WriteLine($"結果: {(int)response.StatusCode} {response.StatusCode}");

            // ステータスコードに応じた分岐処理
            switch (response.StatusCode)
            {
                case HttpStatusCode.OK:
                    string content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine("成功: データを取得しました。");
                    break;

                case HttpStatusCode.Created:
                    Console.WriteLine("成功: リソースが作成されました。");
                    break;

                case HttpStatusCode.NotFound:
                    Console.WriteLine("エラー: 指定されたページは見つかりませんでした。");
                    break;

                case HttpStatusCode.InternalServerError:
                    Console.WriteLine("エラー: サーバー内部でエラーが発生しています。");
                    break;
                
                case HttpStatusCode.ServiceUnavailable:
                    Console.WriteLine("エラー: サーバーはメンテナンス中か高負荷状態です。");
                    break;

                default:
                    // IsSuccessStatusCodeプロパティを使えば、200番台(200-299)をまとめて判定できます
                    if (response.IsSuccessStatusCode)
                    {
                        Console.WriteLine("成功: その他の正常応答です。");
                    }
                    else
                    {
                        Console.WriteLine("失敗: その他のエラーです。");
                    }
                    break;
            }
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"通信エラー(DNS解決失敗など): {ex.Message}");
        }
    }
}

HttpStatusCode 代表的な値一覧

よく使用されるステータスコードの一覧です。

フィールド値 (int)意味
OK200リクエストは成功しました。最も一般的な成功レスポンスです。
Created201リクエストは成功し、新しいリソースが作成されました(POST等)。
NoContent204リクエストは成功しましたが、返すコンテンツはありません。
MovedPermanently301リクエストされたリソースは恒久的に移動しました(転送)。
BadRequest400リクエスト構文が誤っているため、サーバーが処理できませんでした。
Unauthorized401認証が必要です。または認証に失敗しました。
Forbidden403リソースへのアクセス権限がありません(認証されていても拒否)。
NotFound404リクエストされたリソースが見つかりませんでした。
Conflict409リクエストが現在のサーバーの状態と競合しています。
InternalServerError500サーバー内部で予期せぬエラーが発生しました。
ServiceUnavailable503サーバーは現在利用できません(過負荷やメンテナンス)。

カスタムポイント

  • 成功かどうかの簡易判定: 特定のコードではなく「成功したかどうか(200-299)」だけを知りたい場合は、response.IsSuccessStatusCode プロパティ(bool型)を使用するのが便利です。
  • 強制例外: ステータスコードがエラーの場合に即座に例外を発生させたい場合は、response.EnsureSuccessStatusCode() を呼び出します。これにより、404や500の時に HttpRequestException がスローされます。
  • 整数による判定: HttpStatusCode 列挙型に定義されていない特殊なコードが返ってくる可能性がある場合は、(int)response.StatusCode で数値として取得し、判定を行ってください。

注意点

  1. 例外との違い: GetAsync メソッドは、サーバーから応答(404や500を含む)がある限り例外を投げません。例外が発生するのは「DNS解決失敗」「タイムアウト」「ネットワーク切断」などの通信レベルのエラー時のみです。したがって、try-catch だけでなく StatusCode のチェックが必須です。
  2. リダイレクト: HttpClient のデフォルト設定では、301や302のリダイレクトは自動的に追跡(新しいURLへ移動)され、最終的なページのステータスコード(通常は200)が返ります。3xx系を検知したい場合は、HttpClientHandler.AllowAutoRedirect = false の設定が必要です。

応用

処理の成功を保証するパターン

エラー時に処理を中断させたい場合、EnsureSuccessStatusCode を使うとコードを短く記述できます。

var response = await _client.GetAsync(url);

// 200-299以外ならここで例外が発生し、catchブロックへ飛ぶ
response.EnsureSuccessStatusCode(); 

// ここに来る=成功していることが保証される
var html = await response.Content.ReadAsStringAsync();

まとめ

Web API連携やスクレイピングにおいて、HTTPステータスコードの確認はエラーハンドリングの要です。正常系(200 OK)だけでなく、リソース不在(404)やサーバーエラー(500系)を明示的にハンドリングすることで、アプリケーションの堅牢性が向上します。基本的には列挙型 HttpStatusCode を使用して可読性を高め、必要に応じて IsSuccessStatusCodeEnsureSuccessStatusCode を使い分ける実装が推奨されます。

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

この記事を書いた人

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

目次