HttpStatusCode'un başarılı mı yoksa başarısız mı olduğunu kontrol etme


95

Aşağıdaki değişkene sahip olduğumu varsayalım:

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

Bunun bir başarı durum kodu mu yoksa başarısızlık mı olduğunu nasıl kontrol edebilirim?

Örneğin şunları yapabilirim:

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

Bir çeşit beyaz listeye de sahip olabilirim:

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

Bu alternatiflerin hiçbiri beni ikna etmiyor ve bu işi benim için yapabilecek bir .NET sınıfı veya yöntemi umuyordum, örneğin:

bool isSuccess = HttpUtilities.IsSuccess(status);

Yapmanız gereken int code = (int)Response.StatusCodekendi oluşturmanız gerekecektir oradan Enumörnek çalışma için burada kontrol stackoverflow.com/questions/1330856/...
methodman

HttpClientSınıfı kullanma şansınız var mı?
dcastro

1
@dcastro Hayır, üzgünüm. Ben kullanıyorum üst düzey (veya olmayabilir) dahili olarak kullanabilir API. API, yanıtın durum kodunu açığa çıkarır ancak içini açığa çıkarmaz HttpResponseMessage, örneğin
Matias Cicero

@MatiCicero Bu çok kötü: / HttpResponseMessage.IsSuccessStatusCodeİlk yaklaşımınızla tamamen aynı olan ( cevabıma bakın) uygulamasını her zaman yeniden kullanabilir ve onu HttpStatusCodetür üzerinde bir genişletme yöntemi yapabilirsiniz .
dcastro

Yanıtlar:


180

HttpClientSınıfı kullanıyorsanız , o zaman HttpResponseMessagegeri alırsınız .

Bu sınıf, IsSuccessStatusCodekontrolü sizin için yapacak yararlı bir özelliğe sahiptir .

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

Merak ediyorsanız, bu özellik şu şekilde uygulanır :

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

Eğer eğer sadece bu algoritmayı yeniden kullanabilirsiniz Yani değil kullanarakHttpClient doğrudan.

EnsureSuccessStatusCodeYanıtın başarılı olmaması durumunda bir istisna atmak için de kullanabilirsiniz .


1
Bilginize: Benim için 'cevap, başarılı' oldu.
Topher Birth

Cevabınız oldukça faydalı ama şimdi şöyle çalışıyor: if (response.IsCompletedSuccessfully) {//}
salman

12

HttpResponseMessage sınıfı, bir IsSuccessStatusCode özelliğine sahiptir, kaynak koduna bakıldığında, usr zaten 200-299'un muhtemelen yapabileceğinizin en iyisi olduğunu söylediği gibi bu şekildedir.

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

11

Kabul edilen yanıt, ikinci bölümünde sihirli sayılar (standart olmasına rağmen) içerdiğinden beni biraz rahatsız ediyor. Ve birinci kısım, cevabıma yakın olmasına rağmen, düz tamsayı durum kodlarına genel değildir.

HttpResponseMessage'ı durum kodunuzla somutlaştırarak ve başarı olup olmadığını kontrol ederek tam olarak aynı sonucu elde edebilirsiniz. Değer sıfırdan küçük veya 999'dan büyükse bağımsız değişken istisnası atar.

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

Bu tam olarak kısa değil, ancak bir uzantı yapabilirsiniz.


Bu benim için mükemmel bir şekilde çalıştı çünkü sadece bir HttpStatusCode'um vardı ve bir Yanıt mesajı yoktu. Aferin!
Todd Vance

6
"Kabul edilen cevap, sihirli sayılar içerdiğinden beni biraz rahatsız ediyor (standart olmasına rağmen)" - Standartlaştırılmışlarsa, iyi anlaşılmışlarsa ve asla değişmeyeceklerse "sihirli" değildirler. Kodları doğrudan kullanmanın kesinlikle yanlış bir tarafı yoktur. Eğer varsa IsSuccessStatusCodeo zaman büyük bir (kabul cevap için söylediği gibi.), Kullanmak Aksi takdirde, her yerde bu kontrol yaptıktan sürece bir soyutlama kullanarak kendi cruft katmayan
Ed S.

3
HttpResponseMessageÖzelliklerinden birini kullanmak için örneklemenin iki mantıksal koşulu kontrol etmekten daha fazla zaman aldığını unutmayın int.
Miro J.

10

@TomDoesCode yanıtına ekleme HttpWebResponse kullanıyorsanız, bu uzantı yöntemini ekleyebilirsiniz:

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

8

Uzantı yöntemlerinin keşfedilebilirliği konusunda kısmi bir bilgim var.

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

Ad alanınız kapsam dahilinde olduğu sürece, kullanım olacaktır statusCode.IsSuccessStatusCode().


Uzantı yöntemleri harika, ancak kafam karıştı - bu HTTPClient veya IHTTPClientFactory ile kullanılan HTTPResponseMessage'ın IsSuccessStatusCode özelliği ile aynı şeyi yapmaz mı? @DCastro, .NET'te tam olarak böyle uygulandığını bile bize gösteriyor. 2xx aralığındaki HTTP Durum Kodları için böyle bir uzantı yöntemini ne zaman / neden kullanmalıyım?
sfors, Monica'yı

4
@sfors, evet, peki ya sadece bir HttpStatusCodekapsamınız varsa? Kullanmayan veya yüzeye çıkmayan HttpResponseMessageancak size durum kodunu veren çok sayıda kitaplık vardır .
bojingo

3

Hangi HTTP kaynağını aradığınıza bağlıdır. Genellikle2xxAralık başarı durum kodlarının aralığı olarak tanımlanır. Bu açıkça her HTTP sunucusunun uymayacağı bir kuraldır.

Örneğin, bir web sitesinde bir form göndermek genellikle 302 yönlendirmesi döndürür.

Genel bir yöntem geliştirmek istiyorsanız, o zaman code >= 200 && code < 300fikir muhtemelen en iyi şansınızdır.

Eğer aradığınız takdirde kendi sunucusunu sonra muhtemelen emin üzerinde standardize olduğunu yapmalıdır 200.


2

Bu, her çağrı için yeni bir nesnenin oluşturulmasını ve ardından çöp toplanmasını önleyen önceki yanıtın bir uzantısıdır.

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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.