web-dev-qa-db-ja.com

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

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

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
}

これらの選択肢のいずれも私を納得させるものではありません。

bool isSuccess = HttpUtilities.IsSuccess(status);
75
Matias Cicero

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を直接使用しているnotであれば、このアルゴリズムを再利用できます。

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

137
dcastro

HttpResponseMessageクラスにはIsSuccessStatusCodeプロパティがあり、ソースコードを見ると次のようになっています。usrが既に提案しているように、おそらく200-299が最善です。

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

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

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

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

これは厳密には正確ではありませんが、拡張機能にすることができます。

8
user232548

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

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

私は拡張メソッドの発見可能性に部分的です。

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

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

4
bojingo

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

たとえば、Webサイトでフォームを送信すると、しばしば302リダイレクトが返されます。

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

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

3
usr

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

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);
}
1
Rob Lyndon