Bagaimana cara mendapatkan StatusCode dari HttpRequestException?

90

Saya mungkin melewatkan sesuatu yang jelas di sini.

Saya menggunakan HttpClientlemparan HttpRequestExceptionyang berisi StatusCodedalam string Pesan.

Bagaimana saya bisa mengaksesnya StatusCode?


Edit : Info lebih lanjut, saya menulis pertanyaan ini dengan terburu-buru.

Saya menggunakan HttpClientuntuk mengakses API lain dalam proyek WebApi saya. Ya, saya tahu mengapa saya menelepon EnsureSuccessStatusCode(). Saya ingin menyebarkan beberapa kesalahan ke hilir seperti 404 dan 403.

Yang saya inginkan adalah secara konsisten bertransformasi HttpRequestExceptionmenjadi HttpResponseExceptionmenggunakan custom ExceptionFilterAttribute.

Sayangnya, HttpRequestExceptiontidak ada info tambahan yang bisa saya gunakan selain pesan. Saya berharap untuk mengungkap StatusCodedalam bentuk mentah (int atau enum).

Sepertinya saya bisa:

  1. Gunakan pesan untuk mengganti kode status (bleh)
  2. Atau buat versi saya dari EnsureSuccessStatusCode dan lempar pengecualian yang sebenarnya bisa digunakan.
Kugel
sumber
1
Bisakah Anda menunjukkan sepotong kode?
Hamlet Hakobyan
1
Apa yang Anda maksud dengan "akses kode status itu"?
Marco
Tunjukkan kode yang memberi tahu di mana Anda mendapatkan pengecualian.
Denmark
5
Kawan, apa yang kurang jelas tentang judul pertanyaan ini?
Kugel
1
Apakah Anda berhasil menemukan solusi yang tepat untuk masalah ini? tolong bagikan
Siddharth Pandey

Jawaban:

38

Kode status diteruskan sebagai bagian dari string HttpRequestExceptionsehingga Anda tidak dapat memulihkannya dari pengecualian tersebut saja.

Desain System.Net.Httpmengharuskan Anda mengakses HttpResponseMessage.StatusCodealih-alih menunggu pengecualian.

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

Jika Anda sekarang mengikuti panduan Microsoft , pastikan Anda memahami dengan jelas mengapa panduan ini meminta Anda untuk menelepon HttpResponseMessage.EnsureSucessStatusCode. Jika Anda tidak memanggil fungsi itu, seharusnya tidak ada pengecualian.

Lex Li
sumber
2
Saya mencoba untuk mengatasi masalah lintas sektoral, di sini. Lihat hasil edit saya, mungkin ada solusi yang lebih baik.
Kugel
1
Apakah ini sesuai dengan penggunaan HttpClient.GetStreamAsync (url) karena saya tidak dapat melihat cara melakukan tindakan ini tanpa harus menghapus teks pesan?
Senator
1
@TheSenator Anda harus memanggil GetAsync (uri) atau PostAsync (uri) untuk mendapatkan kembali HttpResponseMessage. Jika Anda mencoba dan mendapatkan konten respons baik dengan membacanya atau menggunakan metode praktis seperti GetStreamAsync, EnsureSuccessStatusCode akan dipanggil.
odyth
7
Yang menimbulkan pertanyaan yang jelas tentang apa gunanya metode kenyamanan yang tersedia jika mereka mengeluarkan pengecualian yang tidak memungkinkan untuk menangani kesalahan secara berguna. Mengotori kode Anda dengan pernyataan if dan throw bukanlah solusi, jadi dari apa yang telah dikatakan di sini tampaknya jawaban yang benar saat ini adalah Anda harus menerapkan ulang metode kemudahan atau EnsureSuccessStatusCode sendiri.
Neutrino
1
Itu lebih mudah diucapkan daripada dilakukan. Pengecualian dapat dilempar dari kode pihak ketiga. Misalnya swagger client yang dibuat secara otomatis.
pengguna2555515
27

Untuk apa nilainya, orang ini melakukan sesuatu yang pintar: 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

Dalam kasus di mana saya membutuhkan properti status pengecualian, saya dapat melakukan ini:

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

    return false;
}
Steve
sumber
14
dipilih karena terkadang Anda tidak memiliki akses ke respons, seperti saat Anda dipaksa menggunakan pustaka yang membungkus fungsionalitas dan memberikan pengecualian apa pun.
Kell
4
inti bersih 2.1 HttpClient memiliki GetAsync () dan GetStreamAsync (). Yang pertama akan mengembalikan respons sementara yang lain akan memanggil EnsureSucessStatusCode secara internal dan melontarkan HttpRequestException. Saya tidak memahami ketidakkonsistenan dan itu membuat penanganan kesalahan menjadi sulit, tetapi saya menghargai solusi ini.
smurtagh
3
Menjalankan .NET Core 3.1.5, requestException.InnerExceptionadalah null jadi ini tidak akan berfungsi
Ohad Schneider
3

Seperti yang disebutkan oleh orang lain, juga bukan praktik yang baik untuk mendapatkan StatusCode dari HttpRequestException, hal yang sama dapat dilakukan sebelumnya dengan HttpResponseMessage.StatusCode setelah memeriksa HttpResponseMessage.IsSuccessStatusCode

Bagaimanapun jika karena beberapa kendala / persyaratan seseorang harus membaca StatusCode, Ada dua solusi

  1. Perluas HttpResponseMessage dengan pengecualian khusus Anda yang dijelaskan di sini
  2. Meretas HttpRequestException.ToString untuk mendapatkan StatusCode, Karena pesannya adalah posting konstan yang diperbaiki oleh StatusCode dan Repharse.

Di bawah ini adalah kode dalam System.Net.Http.HttpResponseMessage Dimana SR.net_http_message_not_success_statuscode = "Kode status respon tidak menunjukkan keberhasilan: {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;
    }
Pengungsi Singh Malik
sumber
4
string kesalahan dengan format tertentu adalah bau kode, logika tidak boleh bergantung padanya.
pengguna1496062
1
@ user1496062 Jika kesalahan datang dari sistem eksternal, seringkali tidak ada alternatif.
Ian Warburton
1

Ini berhasil untuk saya

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

Mungkin saya terlambat disini:

Dari .NET 5.0, HttpRequestException memiliki StatusCodeproperti yang akan memiliki nilai jika pengecualian mewakili hasil yang tidak berhasil, jika tidak null. Jadi Anda bisa menggunakan sebagai berikut:

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

Untuk lebih jelasnya ada disini

TanvirArjel
sumber