System.Net.WebException HTTPステータスコード


回答:


248

多分このようなもの...

try
{
    // ...
}
catch (WebException ex)
{
    if (ex.Status == WebExceptionStatus.ProtocolError)
    {
        var response = ex.Response as HttpWebResponse;
        if (response != null)
        {
            Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
        }
        else
        {
            // no http status code available
        }
    }
    else
    {
        // no http status code available
    }
}

しかし、webexceptionの「connectfailure」例外の場合、nullとして応答が返されます。その場合、httpstatusコードを取得するにはどうすればよいですか
Rusty

8
@rusty:できません。接続に失敗した場合、取得するHTTPステータスコードはありません。
LukeH 2014年

4
エラーがProtocolErrorの場合、応答がnullかどうかを確認する必要はありません。このMSDNページの
Andras Toth

5
@AndrasTothただし、ReSharperなどのツールでは、null-checkを省略すると警告が表示されます。いずれにしても、防御的にコーディングすることをお勧めします。
トム・リント

1
HTTPサブステータス値を取得するにはどうすればよいですか?例えば、404.13コンテンツの長さが大きすぎ参考docs.microsoft.com/en-us/iis/configuration/system.webServer/...
Kiquenet

27

null条件演算子?.)を使用すると、1行のコードでHTTPステータスコードを取得できます。

 HttpStatusCode? status = (ex.Response as HttpWebResponse)?.StatusCode;

変数にstatusはが含まれますHttpStatusCode。HTTPエラーコードが送信されないネットワークエラーのような、より一般的なエラーが発生した場合statusは、nullになります。その場合は、検査してex.Statusを取得できますWebExceptionStatus

失敗した場合に説明の文字列をログに記録するだけの場合は、null結合演算子??)を使用して関連するエラーを取得できます。

string status = (ex.Response as HttpWebResponse)?.StatusCode.ToString()
    ?? ex.Status.ToString();

404 HTTPステータスコードの結果として例外がスローされた場合、文字列には「NotFound」が含まれます。一方、サーバーがオフラインの場合、文字列には「ConnectFailure」などが含まれます。

(そして、HTTPサブステータスコードを取得する方法を知りたい人にとっては、不可能です。これは、サーバーにのみログオンし、クライアントに送信されないというMicrosoft IISの概念です。)


?.プレビューのリリース時に、演算子の名前がnull伝播演算子またはnull条件演算子のどちらであったかは不明です。しかし、Atlassianリシャーパーは、そのようなシナリオでnull伝播演算子を使用するよう警告します。null条件演算子とも呼ばれます。
RBT 2017年

1
このパーティーには少し遅れましたが、null条件演算子はC#6.0の機能であるため、それをサポートするコンパイラーを使用する必要があることを警告しています。スタックオーバーフローの回答と詳細。VS 2015+にはデフォルトでそれがありますが、「自分のマシン」以外のビルド/デプロイ環境を使用している場合は、他のことも考慮する必要があります。
CodeHxr

9

これは、WebResponseがHttpWebResponseである場合にのみ機能します。

try
{
    ...
}
catch (System.Net.WebException exc)
{
    var webResponse = exc.Response as System.Net.HttpWebResponse;
    if (webResponse != null && 
        webResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
    {
        MessageBox.Show("401");
    }
    else
        throw;
}

考えられるすべてのHTTPエラーステータスコードではなく、401-Unauthorizedのみを処理するのはなぜですか?これが最悪の答えです
ympostor

4
@ympostorこれは単なる例です。合理的な開発者なら誰でもこれを理解しています。あなたのコメントは、私がこれまで読んだ中で最も軽率です。
pr0gg3r 2017年

9

(私は質問が古いことを理解していますが、それはGoogleのトップヒットの1つです。)

応答コードを知りたい一般的な状況は、例外処理です。C#7以降では、パターンマッチングを使用して、例外が述語と一致する場合にのみ実際にcatch句を入力できます。

catch (WebException ex) when (ex.Response is HttpWebResponse response)
{
     doSomething(response.StatusCode)
}

これは、これが別のレベルのWebException実際の内部例外であった(そして私たちはにのみ関心がある404)この場合など、さらに別のレベルに簡単に拡張できます。

catch (StorageException ex) when (ex.InnerException is WebException wex && wex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.NotFound)

最後に、上記の解決策ではそもそも句を入力していないため、条件に一致しない場合、catch句で例外を再スローする必要がないことに注意してください。


4

このコードを試して、WebExceptionからHTTPステータスコードを取得できます。SLにはWebExceptionStatus.ProtocolErrorが定義されていないため、Silverlightでも機能します。

HttpStatusCode GetHttpStatusCode(WebException we)
{
    if (we.Response is HttpWebResponse)
    {
        HttpWebResponse response = (HttpWebResponse)we.Response;
        return response.StatusCode;
    }
    return null;
}

1
return 0?以上HttpStatusCode?nullable)?
Kiquenet 2018年

これは機能しますか?var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
FMFF

このサンプルで何をしたいのか理解できません。どのような場合にイベントをログに記録したいですか?
セルゲイ

1

あるかどうかはわかりませんが、そのようなプロパティがあった場合、信頼できるとは見なされません。A WebExceptionは、単純なネットワークエラーなど、HTTPエラーコード以外の理由で起動されます。それらには、そのような一致するhttpエラーコードはありません。

そのコードで何を達成しようとしているのか、もう少し詳しく教えてください。必要な情報を取得するより良い方法があるかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.