簡體   English   中英

HttpWebRequest.GetResponse() 失敗時如何獲取錯誤信息

[英]How to get error information when HttpWebRequest.GetResponse() fails

我正在啟動一個 HttpWebRequest,然后檢索它的響應。 有時,我會收到 500(或至少 5##)錯誤,但沒有說明。 我可以控制兩個端點,並希望接收端獲得更多信息。 例如,我想將異常消息從服務器傳遞到客戶端。 這可以使用 HttpWebRequest 和 HttpWebResponse 嗎?

代碼:

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

對此的任何幫助將不勝感激。

這可以使用 HttpWebRequest 和 HttpWebResponse 嗎?

您可以讓您的 Web 服務器簡單地捕獲異常文本並將其寫入響應正文,然后將狀態代碼設置為 500。現在客戶端在遇到 500 錯誤時會拋出異常,但您可以讀取響應流並獲取異常消息。

因此,您可以捕獲一個WebException ,如果從服務器返回非 200 狀態代碼並讀取其正文,則會拋出該異常:

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
}

我在嘗試檢查 FTP 站點上是否存在文件時遇到了這個問題。 如果文件不存在,則在嘗試檢查其時間戳時會出現錯誤。 但是我想通過檢查它的類型來確保錯誤不是別的東西。

WebException上的Response屬性將是FtpWebResponse類型,您可以檢查其StatusCode屬性以查看您有哪個 FTP 錯誤

這是我最終得到的代碼:

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

我遇到過類似的情況:

我試圖在使用 BasicHTTPBinding 的 HTTP 錯誤使用 SOAP 服務的情況下讀取原始響應。

但是,在使用GetResponseStream()讀取響應時,出現錯誤:

流不可讀

所以,這段代碼對我有用:

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

您還可以使用這個庫,它將 HttpWebRequest 和 Response 包裝成基於結果返回對象的簡單方法。 它使用了這些答案中描述的一些技術,並且有大量代碼靈感來自這個和類似線程的答案。 它會自動捕獲任何異常,盡可能多地抽象發出這些 Web 請求所需的樣板代碼,並自動反序列化響應對象。

使用此包裝器的代碼示例非常簡單

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

    }

完全公開這個庫是一個免費的開源包裝庫,我是該庫的作者。 我沒有從中賺錢,但多年來發現它非常有用,並且我相信任何仍在使用 HttpWebRequest / HttpWebResponse 類的人也會這樣做。

它不是靈丹妙葯,但支持 get、post、delete 以及異步和非異步獲取和發布以及 JSON 或 XML 請求和響應。 截至 2020 年 6 月 21 日,它正在積極維護

有時ex.Response也會拋出NullReferenceException所以下面是最好的處理方式

catch (WebException ex)
{
    using (var stream = ex?.Response?.GetResponseStream())
    if(stream != null)
    using (var reader = new StreamReader(stream))
    {
        Console.WriteLine(reader.ReadToEnd());
    }
    // todo...
}
catch (Exception ex)
{
    // todo...
}
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(); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM