HttpWebRequest.GetResponse () başarısız olduğunda hata bilgisi nasıl alınır


87

Bir HttpWebRequest başlatıyorum ve ardından yanıtını alıyorum. Bazen 500 (veya en az 5 ##) hatası alıyorum, ancak açıklama yok. Her iki uç nokta üzerinde kontrolüm var ve alıcı tarafın biraz daha fazla bilgi almasını istiyorum. Örneğin, istisna mesajını sunucudan istemciye iletmek istiyorum. HttpWebRequest ve HttpWebResponse kullanılarak bu mümkün müdür?

Kod:

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)."
}

Bununla ilgili herhangi bir yardım çok takdir edilecektir.


Buna ekleyeceğim, her zaman bir tryifadeyle sarılmış içeriği en aza indirmeniz önerilir . Sizin durumunuzda, usingsatıra kadar olan her şey muhtemelen dışarıda yazılabilir.
SSHunter49

Yanıtlar:


153

HttpWebRequest ve HttpWebResponse kullanılarak bu mümkün müdür?

Web sunucunuzun istisna metnini yakalayıp yanıtın gövdesine yazmasını, ardından durum kodunu 500 olarak ayarlamasını sağlayabilirsiniz. Artık istemci bir 500 hatasıyla karşılaştığında bir istisna atacaktır ancak yanıt akışını okuyabilir ve istisna mesajı.

Böylece , sunucudan 200 olmayan bir durum kodu döndürülürse ve gövdesini okursa atılacak olan bir WebException'ı yakalayabilirsiniz :

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
}

Teşekkür ederim! WebResponse'un kullanıcısı bunu temizleyeceğinden, using ifadesinin içinden gelen akışın using ifadesi dışında kullanılamayacağına dikkat etmek önemlidir. Bu beni birkaç dakikalığına rahatsız etti.
Thorin

@Thorin. İlk ifadeden gelen "akış" bir sonraki ifadeye taşınır. Tıpkı tek satırlık bir EĞER ifadesinde olduğu gibi, örneğin eğer (bir şey) burada-şeyler-yap;
RealityDysfunction

1
GetRequestStreamve istisnalarGetResponse atabilir mi?
PreguntonCojoneroCabrón

@ PreguntonCojoneroCabrón Evet, pek doğru görünmüyor, değil mi. Neyse ki Microsoft, bugünlerde çoğunun kullandığından şüphelendiğim HttpClient sınıfını tanıttı. msdn.microsoft.com/en-us/library/…
Morten Nørgaard

8

Bir FTP sitesinde bir dosyanın var olup olmadığını kontrol etmeye çalışırken bu soruyla karşılaştım. Dosya yoksa, zaman damgasını kontrol etmeye çalışırken bir hata olacaktır. Ancak, türünü kontrol ederek hatanın başka bir şey olmadığından emin olmak istiyorum.

Üzerindeki Responseözellik, sahip olduğunuz FTP hatasını görmek için kendi özelliğini kontrol edebileceğiniz WebExceptiontürde olacaktır .FtpWebResponseStatusCode

İşte bulduğum kod:

    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;
        }
    }

4

Benzer bir durumla karşılaştım:

Bir SOAP hizmetini tüketen bir HTTP hatası durumunda BasicHTTPBinding kullanarak ham yanıtı okumaya çalışıyordum.

Ancak, kullanarak yanıtı okurken GetResponseStream()şu hatayı aldım:

Akış okunamıyor

Yani, bu kod benim için çalıştı:

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();
}

0

HttpWebRequest ve Response'u sonuçlara dayalı olarak nesneleri döndüren basit yöntemlere saran bu kitaplığı da kullanabilirsiniz . Bu cevaplarda açıklanan tekniklerden bazılarını kullanır ve bu ve benzer konulardaki cevaplardan esinlenen birçok koda sahiptir. Herhangi bir istisnayı otomatik olarak yakalar, bu web taleplerini mümkün olduğunca yapmak için gerekli olan en fazla kazan plaka kodunu soyutlamaya çalışır ve yanıt nesnesini otomatik olarak seriyi kaldırır.

Bu sarmalayıcıyı kullanarak kodunuzun nasıl görüneceğine bir örnek,

    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);

    }

Tam açıklama Bu kitaplık ücretsiz bir açık kaynak paket kitaplığıdır ve ben söz konusu kitaplığın yazarıyım. Bundan hiç para kazanmıyorum, ancak yıllar içinde bunu son derece yararlı buldum ve eminim HttpWebRequest / HttpWebResponse sınıflarını kullanan herkes de kullanacaktır.

Bu bir sihirli değnek değildir, ancak JSON veya XML istekleri ve yanıtlarının yanı sıra alma ve gönderme için eşzamansız ve eşzamansız olmayan alma, gönderme, silme işlemlerini destekler. 6/21/2020 itibarıyla aktif olarak bakımı yapılmaktadır.


-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(); 
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.