HttpWebRequest.GetResponse() 失败时如何获取错误信息

发布于 2024-12-02 11:46:43 字数 927 浏览 3 评论 0原文

我正在启动 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)."
}

任何对此的帮助将不胜感激。

I am initiating an HttpWebRequest and then retrieving it's response. Occasionally, I get a 500 (or at least 5##) error, but no description. I have control over both endpoints and would like the receiving end to get a little bit more information. For example, I would like to pass the exception message from server to client. Is this possible using HttpWebRequest and HttpWebResponse?

Code:

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

Any help with this would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

甜妞爱困 2024-12-09 11:46:44
**Answer Updated on 14-03-2022**
HttpWebRequest myHttprequest = null;
HttpWebResponse myHttpresponse = null;
try
{
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)
 {
   //Success code flow
 }
myHttpresponse.Close(); 
}
catch(WebException e) {
    Console.WriteLine("This program is expected to throw WebException on successful run."+
                    "\n\nException Message :" + e.Message);
    if(e.Status == WebExceptionStatus.ProtocolError) {
        Console.WriteLine("Status Code : {0}", 
    ((HttpWebResponse)e.Response).StatusCode);
    Console.WriteLine("Status Description : {0}", 
    ((HttpWebResponse)e.Response).StatusDescription);
}
**Updated Answer with try catch block**
[docs.microsoft][1]
**Answer Updated on 14-03-2022**
HttpWebRequest myHttprequest = null;
HttpWebResponse myHttpresponse = null;
try
{
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)
 {
   //Success code flow
 }
myHttpresponse.Close(); 
}
catch(WebException e) {
    Console.WriteLine("This program is expected to throw WebException on successful run."+
                    "\n\nException Message :" + e.Message);
    if(e.Status == WebExceptionStatus.ProtocolError) {
        Console.WriteLine("Status Code : {0}", 
    ((HttpWebResponse)e.Response).StatusCode);
    Console.WriteLine("Status Description : {0}", 
    ((HttpWebResponse)e.Response).StatusDescription);
}
**Updated Answer with try catch block**
[docs.microsoft][1]
等风来 2024-12-09 11:46:43

使用 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
}

Is this possible using HttpWebRequest and HttpWebResponse?

You could have your web server simply catch and write the exception text into the body of the response, then set status code to 500. Now the client would throw an exception when it encounters a 500 error but you could read the response stream and fetch the message of the exception.

So you could catch a WebException which is what will be thrown if a non 200 status code is returned from the server and read its body:

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
}
因为看清所以看轻 2024-12-09 11:46:43

我在尝试检查 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;
        }
    }

I came across this question when trying to check if a file existed on an FTP site or not. If the file doesn't exist there will be an error when trying to check its timestamp. But I want to make sure the error is not something else, by checking its type.

The Response property on WebException will be of type FtpWebResponse on which you can check its StatusCode property to see which FTP error you have.

Here's the code I ended up with:

    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;
        }
    }
话少心凉 2024-12-09 11:46:43

我遇到了类似的情况:

我尝试使用 BasicHTTPBinding 读取原始响应,以防使用 SOAP 服务时发生 HTTP 错误。

但是,当使用 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();
}

I faced a similar situation:

I was trying to read raw response in case of an HTTP error consuming a SOAP service, using BasicHTTPBinding.

However, when reading the response using GetResponseStream(), got the error:

Stream not readable

So, this code worked for me:

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();
}
等风也等你 2024-12-09 11:46:43

您还可以使用此库,它将 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 日,它正在积极维护中

You can also use this library which wraps HttpWebRequest and Response into simple methods that return objects based on the results. It uses some of the techniques described in these answers and has plenty of code inspired by answers from this and similar threads. It automatically catches any exceptions, seeks to abstract as much boiler plate code needed to make these web requests as possible, and automatically deserializes the response object.

An example of what your code would look like using this wrapper is as simple as

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

    }

Full disclosure
This library is a free open source wrapper library, and I am the author of said library. I make no money off of this but have found it immensely useful over the years and am sure anyone who is still using the HttpWebRequest / HttpWebResponse classes will too.

It is not a silver bullet but supports get, post, delete with both async and non-async for get and post as well as JSON or XML requests and responses. It is being actively maintained as of 6/21/2020

梦境 2024-12-09 11:46:43

有时 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...
}

Sometimesex.Response also throws NullReferenceException so below is the best way to handle

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...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文