HttpRequestExceptionからStatusCodeを取得するにはどうすればよいですか?


90

私はおそらくここで明白な何かを見逃しています。

メッセージ文字列に含まれるHttpClientスローHttpRequestExceptionを使用していStatusCodeます。

どうすればそれにアクセスできますStatusCodeか?


編集:詳細、私は急いでこの質問を書きました。

HttpClientWebApiプロジェクト内の別のAPIにアクセスするために使用しています。はい、私はなぜ私が呼んでいるのか知っていEnsureSuccessStatusCode()ます。404や403などのエラーをダウンストリームに伝播したいと思います。

私が欲しかったのは、一貫HttpRequestExceptionHttpResponseExceptionてカスタムを使用するように変換することExceptionFilterAttributeでした。

残念ながら、HttpRequestExceptionメッセージ以外に使用できる追加情報はありません。私はStatusCode生の(intまたはenum)形式で発見したいと思っていました。

私はどちらかができるように見えます:

  1. メッセージを使用してステータスコードを切り替えます(bleh)
  2. または、EnsureSuccessStatusCodeのバージョンを作成して、実際に使用できる例外をスローします。

1
コードを表示できますか?
ハムレットハコビアン2014年

1
「そのステータスコードにアクセスする」とはどういう意味ですか?
マルコ

例外が発生している場所を示すコードを表示します。
デンマーク語2014年

5
みんなこの質問のタイトルについてはっきりしないことは何ですか?
クーゲル2014年

1
この問題の適切な解決策を見つけることができましたか?共有してください
Siddharth Pandey 2014年

回答:


38

ステータスコードが文字列の一部としてに渡されました HttpRequestExceptionため、このような例外だけから回復することはできません。

の設計でSystem.Net.HttpHttpResponseMessage.StatusCode、例外を待つのではなく、アクセスする必要があります。

http://msdn.microsoft.com/en-us/library/system.net.http.httpresponsemessage(v=vs.110).aspx

現在Microsoftガイドに従っいる場合は、電話をかけるように求められる理由を明確に理解してくださいHttpResponseMessage.EnsureSucessStatusCode。その関数を呼び出さなくても、例外はありません。


2
ここで、横断的関心事に対処しようとしています。私の編集を見てください、多分もっと良い解決策があります。
クーゲル2014年

1
メッセージテキストを削除せずにこのアクションを実行する方法がわからないため、これはHttpClient.GetStreamAsync(url)の使用に適合しますか?
上院議員

1
@TheSenator HttpResponseMessageを取得するには、GetAsync(uri)またはPostAsync(uri)を呼び出す必要があります。応答を読み取るか、GetStreamAsyncなどの便利なメソッドを使用して応答の内容を取得しようとすると、EnsureSuccessStatusCodeが内部で呼び出されます。
odyth 2018年

7
これは、エラーを有効に処理することを可能にしない例外をスローした場合に、便利なメソッドがまったく利用できないことのポイントは何であるかという明らかな疑問を投げかけます。コードにifステートメントとthrowステートメントを散らかすことは解決策ではないため、ここで述べたことから、現在のところ正しい答えは、コンビニエンスメソッドまたはEnsureSuccessStatusCodeのいずれかを自分で再実装する必要があるということです。
ニュートリノ

1
それは口で言うほど簡単ではありません。例外はサードパーティのコードからスローされる可能性があります。たとえば、自動生成されたSwaggerクライアント。
user25555 1520

27

その価値のために、この男は何か賢いことをしました: https //social.msdn.microsoft.com/Forums/vstudio/en-US/dc9bc426-1654-4319-a7fb-383f00b68def/c-httpresponsemessage-throws-exception-httprequestexception -webexception-the-remote-name?forum = csharpgeneral

例外ステータスプロパティが必要な場合は、次のように実行できます。

catch (HttpRequestException requestException)
{
    if (requestException.InnerException is WebException webException && webException.Status == WebExceptionStatus.NameResolutionFailure)
    {
        return true;
    }

    return false;
}

14
機能をラップして例外をスローするライブラリを使用せざるを得ない場合など、応答にアクセスできない場合があるため、賛成票を投じました。
ケル2017年

4
.netコア2.1HttpClientにはGetAsync()とGetStreamAsync()があります。1つ目は応答を返し、もう1つはEnsureSucessStatusCodeを内部的に呼び出して、HttpRequestExceptionをスローします。不整合がわかりにくく、エラーの処理が難しくなりますが、この回避策には感謝しています。
smurtagh

3
.NET Core 3.1.5の実行requestException.InnerExceptionはnullであるため、これは機能しません
OhadSchneider20年

3

他の人も述べているように、HttpRequestExceptionからStatusCodeを取得することはお勧めできません。これは、HttpResponseMessage.IsSuccessStatusCodeを確認した後、HttpResponseMessage.StatusCodeを使用して事前に行うことができます。

とにかく、何らかの制約/要件のためにStatusCodeを読み取らなければならない場合、2つの解決策があります

  1. ここで説明するカスタム例外を使用してHttpResponseMessageを拡張しました
  2. HttpRequestException.ToStringをハックしてStatusCodeを取得します。メッセージは、StatusCodeとRepharseによって修正された一定の投稿であるためです。

以下は、System.Net.Http.HttpResponseMessageのコードです。SR.net_http_message_not_success_statuscode= "応答ステータスコードは成功を示していません:{0}({1})。"

public HttpResponseMessage EnsureSuccessStatusCode()
    {
        if (!this.IsSuccessStatusCode)
        {
            if (this.content != null)
            {
                this.content.Dispose();
            }
            throw new HttpRequestException(string.Format(CultureInfo.InvariantCulture, SR.net_http_message_not_success_statuscode, new object[]
            {
                (int)this.statusCode,
                this.ReasonPhrase
            }));
        }
        return this;
    }

4
特定の形式のエラー文字列はコードの臭いであり、ロジックはそれらに依存してはなりません。
user1496062 2017

1
@ user1496062エラーが外部システムから発生した場合、多くの場合、代替手段はありません。
Ian Warburton

1

これは私のために働いた

var response = ex.Response;
var property = response.GetType().GetProperty("StatusCode");
if ( property != null && (HttpStatusCode)property.GetValue(response) == HttpStatusCode.InternalServerError)

0

多分私はここで遅れています:

.NET 5.0からは、 HttpRequestException持っているStatusCode例外は非成功した結果、そうでない場合はnullを表す場合は値を持つことになりますプロパティを。したがって、次のように使用できます。

try
{
   // Your code
}
catch (HttpRequestException httpRequestException)
{
   if ((int)httpRequestException.StatusCode == 401)
   {
        // Show unauthorized error message
   }
   else 
   {
       // Other error message
   }
}

詳細はこちら

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