HttpStatusCodeが成功または失敗を表すかどうかの確認


93

次の変数があるとします。

System.Net.HttpStatusCode status = System.Net.HttpStatusCode.OK;

これが成功ステータスコードか失敗コードかを確認するにはどうすればよいですか?

たとえば、次のことができます。

int code = (int)status;
if(code >= 200 && code < 300) {
    //Success
}

また、ある種のホワイトリストを作成することもできます。

HttpStatusCode[] successStatus = new HttpStatusCode[] {
     HttpStatusCode.OK,
     HttpStatusCode.Created,
     HttpStatusCode.Accepted,
     HttpStatusCode.NonAuthoritativeInformation,
     HttpStatusCode.NoContent,
     HttpStatusCode.ResetContent,
     HttpStatusCode.PartialContent
};
if(successStatus.Contains(status)) //LINQ
{
    //Success
}

これらの選択肢のどれも私を納得させず、私はこの仕事を私のために行うことができる.NETクラスまたはメソッドを望んでいました:

bool isSuccess = HttpUtilities.IsSuccess(status);

あなたがする必要がint code = (int)Response.StatusCodeあり、あなたがあなた自身の作成する必要がありますから、Enum実施例のためにここにチェックをstackoverflow.com/questions/1330856/...
メソッド・マン

たまたまHttpClientクラスを利用していますか?
dcastro

1
@dcastroいいえ、ごめんなさい。私が使用している高レベルの内部でそれを使用することができます(またはしない場合があります)APIを。APIは応答のステータスコードを公開しますが、HttpResponseMessageたとえば内部を公開しません
Matias Cicero

@MatiCiceroひどすぎる:/ HttpResponseMessage.IsSuccessStatusCode最初のアプローチとまったく同じ(私の回答を参照)の実装をいつでも再利用でき、HttpStatusCode型の拡張メソッドにすることができます。
dcastro

回答:


173

HttpClientクラスを使用している場合は、返金されますHttpResponseMessage

このクラスにはIsSuccessStatusCode、チェックを実行するという便利なプロパティがあります。

using (var client = new HttpClient())
{
    var response = await client.PostAsync(uri, content);
    if (response.IsSuccessStatusCode)
    {
        //...
    }
}

気になる方のために、このプロパティは次のように実装されています。

public bool IsSuccessStatusCode
{
    get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}

したがって、直接使用しない場合は、このアルゴリズムを再利用できますHttpClient

を使用EnsureSuccessStatusCodeして、応答が成功しなかった場合に例外をスローすることもできます。


参考までに:「response.IsSuccessful」でした。
トファーの誕生

あなたの答えはかなり役に立ちますが、今は次のように機能します:if(response.IsCompletedSuccessfully){//}
salman

12

HttpResponseMessageクラスにはIsSuccessStatusCodeプロパティがあり、ソースコードを見ると次のようになっているので、usrはすでに200〜299が最善であると示唆しています。

public bool IsSuccessStatusCode
{
    get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}

11

受け入れられた回答は、その2番目の部分にマジックナンバーが含まれているため(標準ではありますが)、少し気になります。そして、最初の部分は単純な整数ステータスコードに一般的ではありませんが、私の答えに近いです。

ステータスコードを使用してHttpResponseMessageをインスタンス化し、成功を確認することで、まったく同じ結果を得ることができます。値がゼロより小さいか999より大きい場合は、引数例外をスローします。

if (new HttpResponseMessage((HttpStatusCode)statusCode).IsSuccessStatusCode)
{
    // ...
}

これは正確ではありませんが、拡張することもできます。


HttpStatusCodeしかなく、Responseメッセージはなかったので、これは完全に機能しました。よくやった!
トッドヴァンス2017年

5
「受け入れられた回答には、マジックナンバーが含まれているため、少し気になります(標準的なものですが)」-標準化され、よく理解されており、決して変更されない場合、「マジック」ではありません。コードを直接使用してもまったく問題はありません。それがIsSuccessStatusCode良ければ、それを使用します(受け入れられた回答がそうであるように)。それ以外の場合は、このチェックをすべての場所で実行しない限り、抽象化を使用して独自の残骸を追加しないでください
Ed S.

1
HttpResponseMessageプロパティの1つを使用するためのインスタンス化には、を使用して2つの論理条件をチェックするよりも時間がかかることに注意してくださいint
ミロJ.

10

@TomDoesCode回答への追加HttpWebResponseを使用している場合は、この拡張メソッドを追加できます。

public static bool IsSuccessStatusCode(this HttpWebResponse httpWebResponse)
{
    return ((int)httpWebResponse.StatusCode >= 200) && ((int)httpWebResponse.StatusCode <= 299);
}

8

私は拡張メソッドの発見可能性に不満です。

public static class HttpStatusCodeExtensions
{
    public static bool IsSuccessStatusCode(this HttpStatusCode statusCode)
    {
        var asInt = (int)statusCode;
        return asInt >= 200 && asInt <= 299;
    }
}

名前空間がスコープ内にある限り、使用法はになりますstatusCode.IsSuccessStatusCode()


2
おそらくasInt> = 200が必要でしょう
ジム・オニール

拡張メソッドはかっこいいですが、混乱しています。これは、HTTPClientまたはIHTTPClientFactoryで使用されるHTTPResponseMessageのIsSuccessStatusCodeプロパティと同じことをしませんか?@DCastroは、.NETでもこのように実装されていることを示しています。2xxの範囲のHTTPステータスコードにこのような拡張メソッドを使用するのはいつ/なぜですか?
sforsはモニカを

4
@sfors、はい、しかしHttpStatusCodeスコープ内にいる場合はどうなりますか?使用または表示されないHttpResponseMessageがステータスコードを提供するライブラリはたくさんあります。
bojingo

3

呼び出すHTTPリソースによって異なります。通常、2xx範囲は成功ステータスコードの範囲として定義されます。これは明らかに、すべてのHTTPサーバーが準拠するわけではない規則です。

たとえば、ウェブサイトでフォームを送信すると、302リダイレクトが返されることがよくあります。

一般的な方法を考案したい場合は、 code >= 200 && code < 300アイデアはおそらくあなたのベストショットです。

独自のサーバーを呼び出す場合は、おそらくで標準化する必要があります200


2

これは前の回答の拡張であり、呼び出しごとに新しいオブジェクトの作成とその後のガベージコレクションを回避します。

public static class StatusCodeExtensions
{
    private static readonly ConcurrentDictionary<HttpStatusCode, bool> IsSuccessStatusCode = new ConcurrentDictionary<HttpStatusCode, bool>();
    public static bool IsSuccess(this HttpStatusCode statusCode) => IsSuccessStatusCode.GetOrAdd(statusCode, c => new HttpResponseMessage(c).IsSuccessStatusCode);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.