StatusCode'u HttpRequestException'dan nasıl alabilirim?


90

Muhtemelen burada bariz bir şeyi kaçırıyorum

HttpClientHangi atışları kullanıyorumHttpRequestException o içeren StatusCodeİleti dizede.

Buna nasıl erişebilirim StatusCode?


Düzenle : Daha fazla bilgi, bu soruyu aceleyle yazdım.

kullanıyorum HttpClientWebApi projemde başka bir API'ye erişmek . Evet, neden aradığımı biliyorum EnsureSuccessStatusCode(). 404 ve 403 gibi bazı hataları aşağı yönde yaymak istiyorum.

Tek istediğim tutarlı bir şekilde HttpRequestExceptiondönüşmektiHttpResponseException özel kullanarak ExceptionFilterAttribute.

Ne yazık ki, HttpRequestException mesajın yanında kullanabileceğim herhangi bir ekstra bilgi taşımıyor. StatusCodeHam (int veya enum) formda ortaya çıkarmayı umuyordum .

Görünüşe göre ben de yapabilirim:

  1. Durum kodunu değiştirmek için mesajı kullanın (bleh)
  2. Veya benim EnsureSuccessStatusCode sürümümü oluşturun ve gerçekten kullanılabilir olan istisnaları atın.

1
Bir kod parçası gösterebilir misin?
Hamlet Hakobyan

1
"Bu durum koduna eriş" ile ne demek istiyorsun?
Marco

Kodu gösterin, istisnayı nereden aldığınızı söyleyin.
danimarka

5
Beyler, bu sorunun başlığı hakkında net olmayan nedir?
Kugel

1
Bu soruna uygun bir çözüm bulmayı başardınız mı? lütfen paylaşın
Siddharth Pandey

Yanıtlar:


38

Durum kodu bir dizenin parçası olarak aktarıldı HttpRequestException böylece onu bu tür istisnalardan tek başına kurtaramazsınız.

Tasarımı , istisnayı beklemek yerine System.Net.Httperişmenizi gerektirir HttpResponseMessage.StatusCode.

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

Şimdi Microsoft kılavuzunu takip ediyorsanız , neden aramanızı istediğini açıkça anladığınızdan emin olun HttpResponseMessage.EnsureSucessStatusCode. Bu işlevi çağırmazsanız, istisna olmamalıdır.


2
Burada kesişen bir endişeyi ele almaya çalışıyorum. Düzenlememe bak, belki daha iyi bir çözüm vardır.
Kugel

1
Mesaj metnini çıkarmak zorunda kalmadan bu eylemi gerçekleştirmenin bir yolunu göremediğim için bu, HttpClient.GetStreamAsync (url) kullanımına uyuyor mu?
Senatör

1
@TheSenator HttpResponseMessage'ı geri almak için GetAsync (uri) veya PostAsync (uri) çağırmanız gerekir. Yanıtın içeriğine ya okuyarak ya da GetStreamAsync gibi bir kolaylık yöntemi kullanarak ulaşmaya çalışırsanız, başlık altında EnsureSuccessStatusCode çağrılır.
odyth

7
Bu, hatayı yararlı bir şekilde ele almayı mümkün kılmayan istisnalar atarlarsa, elverişli yöntemlerin amacının ne olduğu sorusunu doğurur. Kodunuzu if ve throw ifadeleri ile karıştırmak çözüm değildir, bu nedenle burada söylenenlere göre şu anda doğru cevap, kolaylık yöntemlerini veya EnsureSuccessStatusCode'u kendiniz uygulamanız gerektiğidir.
Neutrino

1
Söylemesi yapmaktan daha kolay. İstisna, bir 3. taraf kodundan atılabilir. Örneğin, otomatik olarak oluşturulmuş havalı müşteri.
user2555515

27

Değeri ne olursa olsun, bu adam akıllıca bir şey yaptı: https://social.msdn.microsoft.com/Forums/vstudio/en-US/dc9bc426-1654-4319-a7fb-383f00b68def/c-httpresponsemessage-throws-exception-httprequestexception -webexception-the-uzak-adı? forum = csharpgeneral

Bir istisna durumu özelliğine ihtiyacım olduğu durumda, bunu yapabilirim:

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

    return false;
}

14
oyu artırdığından, bazen yanıta erişiminiz olmaz, örneğin, işlevselliği saran ve herhangi bir istisna atan bir kitaplık kullanmaya zorlandığınızda olduğu gibi.
Kell

4
.net çekirdeği 2.1 HttpClient, GetAsync () ve GetStreamAsync () 'e sahiptir. İlki bir yanıt döndürürken, diğeri EnsureSucessStatusCode'u dahili olarak çağırır ve bir HttpRequestException oluşturur. Tutarsızlığı anlamıyorum ve hataları ele almayı zorlaştırıyor, ancak bu geçici çözümü takdir ediyorum.
smurtagh

3
.NET Core 3.1.5'i çalıştırmak requestException.InnerExceptionboş olduğundan bu işe yaramaz
Ohad Schneider

3

Başkaları tarafından da belirtildiği gibi, StatusCode'u HttpRequestException'dan almak iyi bir uygulama değildir, aynısı HttpResponseMessage.IsSuccessStatusCode kontrol edildikten sonra HttpResponseMessage.StatusCode ile önceden yapılabilir.

Her neyse, bazı kısıtlamalar / gereksinimler nedeniyle birinin Durum Kodunu okuması gerekiyorsa, iki çözüm olabilir

  1. HttpResponseMessage'ı burada açıklanan özel istisnanızla genişletin
  2. Durum Kodunu almak için HttpRequestException.ToString üzerinde Hack, Mesaj StatusCode ve Repharse tarafından sabitlenmiş sabit bir postadır.

Aşağıda System.Net.Http.HttpResponseMessage'daki kod bulunmaktadır. Burada SR.net_http_message_not_success_statuscode = "Yanıt durum kodu başarıyı göstermez: {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
belirli bir biçime sahip hata dizeleri bir kod kokusudur, mantık asla bunlara bağlı olmamalıdır.
user1496062

1
@ user1496062 Hatalar harici bir sistemden geldiğinde, genellikle başka bir alternatif yoktur.
Ian Warburton

1

Bu benim için çalıştı

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

0

Belki buraya geç kaldım:

.NET 5.0 itibaren, HttpRequestException bir sahiptir StatusCodeistisna aksi takdirde null adlı olmayan bir başarılı bir sonuç temsil ediyorsa bir değere sahip olacaktır özelliği. Yani aşağıdaki gibi kullanabilirsiniz:

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

Daha fazla ayrıntı için buradadır

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.