Bagaimana mendapatkan informasi kesalahan ketika HttpWebRequest.GetResponse () gagal

87

Saya memulai HttpWebRequest dan kemudian mengambil tanggapannya. Kadang-kadang, saya mendapatkan kesalahan 500 (atau setidaknya 5 ##), tetapi tidak ada deskripsi. Saya memiliki kendali atas kedua titik akhir dan ingin ujung penerima mendapatkan sedikit lebih banyak informasi. Misalnya, saya ingin meneruskan pesan pengecualian dari server ke klien. Apakah ini mungkin menggunakan HttpWebRequest dan HttpWebResponse?

Kode:

try
{
    HttpWebRequest webRequest = HttpWebRequest.Create(URL) as HttpWebRequest;
    webRequest.Method = WebRequestMethods.Http.Get;
    webRequest.Credentials = new NetworkCredential(Username, Password);
    webRequest.ContentType = "application/x-www-form-urlencoded";
    using(HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse)
    {
        if(response.StatusCode == HttpStatusCode.OK)
        {
            // Do stuff with response.GetResponseStream();
        }
    }
}
catch(Exception ex)
{
    ShowError(ex);
    // if the server returns a 500 error than the webRequest.GetResponse() method
    // throws an exception and all I get is "The remote server returned an error: (500)."
}

Bantuan apa pun dengan ini akan sangat dihargai.

Trevor
sumber
Saya hanya akan menambahkan ini, selalu disarankan untuk meminimalkan konten yang dibungkus oleh trypernyataan. Dalam kasus Anda, semuanya hingga usingbaris mungkin bisa ditulis di luar.
SSHunter49

Jawaban:

153

Apakah ini mungkin menggunakan HttpWebRequest dan HttpWebResponse?

Anda dapat membuat server web Anda cukup menangkap dan menulis teks pengecualian ke dalam tubuh respons, lalu menyetel kode status ke 500. Sekarang klien akan melempar pengecualian ketika menemukan kesalahan 500 tetapi Anda dapat membaca aliran respons dan mengambil pesan pengecualian.

Jadi Anda bisa menangkap WebException yang akan dilempar jika kode status bukan 200 dikembalikan dari server dan membaca tubuhnya:

catch (WebException ex)
{
    using (var stream = ex.Response.GetResponseStream())
    using (var reader = new StreamReader(stream))
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}
catch (Exception ex)
{
    // Something more serious happened
    // like for example you don't have network access
    // we cannot talk about a server exception here as
    // the server probably was never reached
}
Darin Dimitrov
sumber
Terima kasih! Penting untuk diperhatikan bahwa aliran dari dalam pernyataan using tidak akan tersedia di luar pernyataan using, karena disposer WebResponse akan menghapusnya. Ini membuat saya tersandung selama beberapa menit.
Thorin
@Thorin. "Arus" dari pernyataan pertama dilanjutkan ke pernyataan berikutnya. Persis seperti dalam pernyataan IF baris tunggal, misalnya if (sesuatu) lakukan-barang-di sini;
RealityDysfunction
1
GetRequestStreamdan GetResponsebisa melempar pengecualian ?
PreguntonCojoneroCabrón
@ PreguntonCojoneroCabrón Ya, sepertinya tidak benar, bukan. Untungnya Microsoft memperkenalkan kelas HttpClient, yang saya curigai sebagian besar menggunakan hari ini. msdn.microsoft.com/en-us/library/…
Morten Nørgaard
8

Saya menemukan pertanyaan ini saat mencoba memeriksa apakah ada file di situs FTP atau tidak. Jika file tidak ada, akan terjadi kesalahan saat mencoba memeriksa stempel waktunya. Tetapi saya ingin memastikan bahwa kesalahan tersebut bukanlah sesuatu yang lain, dengan memeriksa tipenya.

The Responseproperti pada WebExceptionakan jenis FtpWebResponsedi mana Anda dapat memeriksa nya StatusCodeproperti untuk melihat mana kesalahan FTP Anda miliki.

Inilah kode yang saya dapatkan:

    public static bool FileExists(string host, string username, string password, string filename)
    {
        // create FTP request
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + host + "/" + filename);
        request.Credentials = new NetworkCredential(username, password);

        // we want to get date stamp - to see if the file exists
        request.Method = WebRequestMethods.Ftp.GetDateTimestamp;

        try
        {
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            var lastModified = response.LastModified;

            // if we get the last modified date then the file exists
            return true;
        }
        catch (WebException ex)
        {
            var ftpResponse = (FtpWebResponse)ex.Response;

            // if the status code is 'file unavailable' then the file doesn't exist
            // may be different depending upon FTP server software
            if (ftpResponse.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
            {
                return false;
            }

            // some other error - like maybe internet is down
            throw;
        }
    }
Simon_Weaver
sumber
4

Saya menghadapi situasi yang sama:

Saya mencoba membaca respons mentah jika terjadi kesalahan HTTP yang memakan layanan SOAP, menggunakan BasicHTTPBinding.

Namun, saat membaca respons menggunakan GetResponseStream(), mendapat kesalahan:

Aliran tidak dapat dibaca

Jadi, kode ini berfungsi untuk saya:

try
{
    response = basicHTTPBindingClient.CallOperation(request);
}
catch (ProtocolException exception)
{
    var webException = exception.InnerException as WebException;
    var rawResponse = string.Empty;

    var alreadyClosedStream = webException.Response.GetResponseStream() as MemoryStream;
    using (var brandNewStream = new MemoryStream(alreadyClosedStream.ToArray()))
    using (var reader = new StreamReader(brandNewStream))
        rawResponse = reader.ReadToEnd();
}
João Paulo Melo
sumber
0

Anda juga dapat menggunakan pustaka ini yang membungkus HttpWebRequest dan Respons ke dalam metode sederhana yang mengembalikan objek berdasarkan hasil. Ini menggunakan beberapa teknik yang dijelaskan dalam jawaban ini dan memiliki banyak kode yang terinspirasi oleh jawaban dari utas ini dan yang serupa. Ini secara otomatis menangkap pengecualian apa pun, berusaha mengabstraksi sebanyak mungkin kode pelat boiler yang diperlukan untuk membuat permintaan web ini sebanyak mungkin, dan secara otomatis deserialisasi objek respons.

Contoh bagaimana kode Anda akan terlihat menggunakan pembungkus ini sesederhana

    var response = httpClient.Get<SomeResponseObject>(request);
    
    if(response.StatusCode == HttpStatusCode.OK)
    {
        //do something with the response
        console.Writeline(response.Body.Id); //where the body param matches the object you pass in as an anonymous type.  
    }else {
         //do something with the error
         console.Writelint(string.Format("{0}: {1}", response.StatusCode.ToString(), response.ErrorMessage);

    }

Pengungkapan penuh Pustaka ini adalah pustaka pembungkus sumber terbuka gratis, dan saya penulis pustaka tersebut. Saya tidak menghasilkan uang dari ini tetapi telah merasa sangat berguna selama bertahun-tahun dan saya yakin siapa pun yang masih menggunakan kelas HttpWebRequest / HttpWebResponse juga akan.

Ini bukan poin perak tetapi mendukung get, post, delete dengan async dan non-async untuk get dan post serta permintaan dan tanggapan JSON atau XML. Ini secara aktif dipertahankan pada 6/21/2020

pat8719
sumber
-3
HttpWebRequest myHttprequest = null;
HttpWebResponse myHttpresponse = null;
myHttpRequest = (HttpWebRequest)WebRequest.Create(URL);
myHttpRequest.Method = "POST";
myHttpRequest.ContentType = "application/x-www-form-urlencoded";
myHttpRequest.ContentLength = urinfo.Length;
StreamWriter writer = new StreamWriter(myHttprequest.GetRequestStream());
writer.Write(urinfo);
writer.Close();
myHttpresponse = (HttpWebResponse)myHttpRequest.GetResponse();
if (myHttpresponse.StatusCode == HttpStatusCode.OK)
 {
   //Perform necessary action based on response
 }
myHttpresponse.Close(); 
Pranesh Janarthanan
sumber