Kode status HTTP System.Net.WebException

153

Apakah ada cara mudah untuk mendapatkan kode status HTTP dari System.Net.WebException?

Gilsham
sumber

Jawaban:

248

Mungkin kira-kira seperti ini ...

try
{
    // ...
}
catch (WebException ex)
{
    if (ex.Status == WebExceptionStatus.ProtocolError)
    {
        var response = ex.Response as HttpWebResponse;
        if (response != null)
        {
            Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
        }
        else
        {
            // no http status code available
        }
    }
    else
    {
        // no http status code available
    }
}
LukeH
sumber
tetapi dalam kasus pengecualian "connectfailure" dari webexception saya mendapatkan respon sebagai nol, dalam hal ini bagaimana saya bisa mendapatkan kode httpstatus
Rusty
8
@usty: Anda tidak bisa. Jika ada kegagalan koneksi maka tidak ada kode status HTTP yang didapat.
LukeH
4
Jika kesalahannya adalah ProtocolError, Anda tidak perlu memeriksa respons untuk nol. Lihat komentar pada contoh di halaman MSDN
Andras Toth
5
@AndrasToth Tapi alat-alat seperti ReSharper akan memberi Anda peringatan jika Anda menghilangkan centang-nol. Dan bagaimanapun, itu adalah praktik yang baik untuk kode pertahanan.
Tom Lint
1
Bagaimana mendapatkan nilai HTTP Substatus ? Misalnya, 404,13 Panjang Konten Referensi Terlalu Besar : docs.microsoft.com/en-us/iis/configuration/system.webServer/…
Kiquenet
27

Dengan menggunakan operator bersyarat nol ( ?.) Anda bisa mendapatkan kode status HTTP dengan satu baris kode:

 HttpStatusCode? status = (ex.Response as HttpWebResponse)?.StatusCode;

Variabel statusakan berisi HttpStatusCode. Ketika ada kegagalan yang lebih umum seperti kesalahan jaringan di mana tidak ada kode status HTTP yang dikirim maka statusakan menjadi nol. Dalam hal ini Anda dapat memeriksa ex.Statusuntuk mendapatkan WebExceptionStatus.

Jika Anda hanya ingin string deskriptif untuk login jika terjadi kegagalan, Anda dapat menggunakan operator null-coalescing ( ??) untuk mendapatkan kesalahan yang relevan:

string status = (ex.Response as HttpWebResponse)?.StatusCode.ToString()
    ?? ex.Status.ToString();

Jika pengecualian dilemparkan sebagai akibat dari kode status HTTP 404 string akan berisi "NotFound". Di sisi lain, jika server sedang offline, string akan berisi "ConnectFailure" dan seterusnya.

(Dan bagi siapa pun yang ingin tahu cara mendapatkan kode HTTP subtatus. Itu tidak mungkin. Ini adalah konsep Microsoft IIS yang hanya masuk di server dan tidak pernah dikirim ke klien.)

Martin Liversage
sumber
Tidak yakin apakah ?.operator itu awalnya bernama operator propagasi nol atau operator kondisional nol selama rilis pratinjau. Tetapi pemanen Atlassian memberi peringatan untuk menggunakan operator propagasi nol dalam skenario seperti itu. Senang mengetahui bahwa itu juga disebut operator null-kondisional.
RBT
1
Agak terlambat ke pesta ini, tetapi peringatan yang adil bahwa operator null-kondisional adalah fitur C # 6.0, jadi orang harus menggunakan kompiler yang mendukungnya. Stack Overflow menjawab dengan rincian lebih lanjut . VS 2015+ memilikinya secara default, tetapi jika seseorang menggunakan segala jenis lingkungan build / deploy selain dari "mesin mereka", hal-hal lain mungkin perlu dipertimbangkan.
CodeHxr
9

ini hanya berfungsi jika WebResponse adalah HttpWebResponse.

try
{
    ...
}
catch (System.Net.WebException exc)
{
    var webResponse = exc.Response as System.Net.HttpWebResponse;
    if (webResponse != null && 
        webResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
    {
        MessageBox.Show("401");
    }
    else
        throw;
}
pr0gg3r
sumber
mengapa hanya berurusan dengan 401-Tidak Resmi alih-alih semua kemungkinan kode status kesalahan HTTP? ini adalah jawaban terburuk
ympostor
4
@ympostor Ini hanyalah sebuah contoh. Setiap pengembang yang masuk akal memahami hal ini. Komentar Anda adalah yang paling tidak masuk akal yang pernah saya baca di sini.
pr0gg3r
9

(Saya menyadari bahwa pertanyaannya sudah lama, tetapi ini termasuk salah satu hit teratas di Google.)

Situasi umum di mana Anda ingin mengetahui kode respons ada dalam penanganan pengecualian. Pada C # 7, Anda dapat menggunakan pencocokan pola untuk benar-benar hanya memasukkan klausa tangkapan jika pengecualian cocok dengan predikat Anda:

catch (WebException ex) when (ex.Response is HttpWebResponse response)
{
     doSomething(response.StatusCode)
}

Ini dapat dengan mudah diperluas ke tingkat lebih lanjut, seperti dalam kasus ini di mana WebExceptionsebenarnya pengecualian dalam yang lain (dan kami hanya tertarik 404):

catch (StorageException ex) when (ex.InnerException is WebException wex && wex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.NotFound)

Akhirnya: perhatikan bagaimana tidak perlu melemparkan kembali pengecualian dalam klausa tangkapan ketika tidak sesuai dengan kriteria Anda, karena kami tidak memasukkan klausa di tempat pertama dengan solusi di atas.

miniyou
sumber
4

Anda dapat mencoba kode ini untuk mendapatkan kode status HTTP dari WebException. Ia bekerja di Silverlight juga karena SL tidak memiliki WebExceptionStatus.ProtocolError didefinisikan.

HttpStatusCode GetHttpStatusCode(WebException we)
{
    if (we.Response is HttpWebResponse)
    {
        HttpWebResponse response = (HttpWebResponse)we.Response;
        return response.StatusCode;
    }
    return null;
}
Sergey
sumber
1
return 0? atau lebih baik HttpStatusCode?( nullable )?
Kiquenet
Akankah ini berhasil? var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
FMFF
Saya tidak mengerti apa yang ingin Anda lakukan dalam sampel ini. Dalam kasus apa Anda ingin acara dicatat?
Sergey
1

Saya tidak yakin apakah ada tetapi jika ada properti seperti itu tidak akan dianggap dapat diandalkan. A WebExceptiondapat dipecat karena alasan selain kode kesalahan HTTP termasuk kesalahan jaringan sederhana. Mereka tidak memiliki kode kesalahan http yang cocok.

Bisakah Anda memberi kami sedikit lebih banyak info tentang apa yang ingin Anda capai dengan kode itu. Mungkin ada cara yang lebih baik untuk mendapatkan informasi yang Anda butuhkan.

JaredPar
sumber