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

C# 如何在HttpWebRequest.GetResponse()失败时获取错误信息,c#,httpwebrequest,httpwebresponse,C#,Httpwebrequest,Httpwebresponse,我正在启动一个HttpWebRequest,然后检索它的响应。偶尔,我会得到500(或至少5)个错误,但没有描述。我可以控制两个端点,希望接收端获得更多的信息。例如,我想将异常消息从服务器传递到客户端。使用HttpWebRequest和HttpWebResponse可以这样做吗 代码: 在此方面的任何帮助都将不胜感激 使用HttpWebRequest和HttpWebResponse可以这样做吗 您可以让web服务器捕获异常文本并将其写入响应主体,然后将状态代码设置为500。现在,客户机在遇到50

我正在启动一个HttpWebRequest,然后检索它的响应。偶尔,我会得到500(或至少5)个错误,但没有描述。我可以控制两个端点,希望接收端获得更多的信息。例如,我想将异常消息从服务器传递到客户端。使用HttpWebRequest和HttpWebResponse可以这样做吗

代码:

在此方面的任何帮助都将不胜感激

使用HttpWebRequest和HttpWebResponse可以这样做吗

您可以让web服务器捕获异常文本并将其写入响应主体,然后将状态代码设置为500。现在,客户机在遇到500错误时会抛出异常,但您可以读取响应流并获取异常消息

因此,如果从服务器返回非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
}
使用HttpWebRequest和HttpWebResponse可以这样做吗

您可以让web服务器捕获异常文本并将其写入响应主体,然后将状态代码设置为500。现在,客户机在遇到500错误时会抛出异常,但您可以读取响应流并获取异常消息

因此,如果从服务器返回非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
属性以查看您的设置

以下是我最终得到的代码:

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

我在检查FTP站点上是否存在文件时遇到了这个问题。如果文件不存在,则在尝试检查其时间戳时会出错。但是我想通过检查它的类型来确保错误不是别的

WebException
上的
Response
属性将属于
FtpWebResponse
类型,您可以在该类型上检查其
StatusCode
属性以查看您的设置

以下是我最终得到的代码:

    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读取原始响应,以防在使用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();
}

我面临着类似的情况:

我试图使用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();
}
您还可以使用它将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);

    }
var response=httpClient.Get(请求);
if(response.StatusCode==HttpStatusCode.OK)
{
//对回应做点什么
console.Writeline(response.Body.Id);//其中Body参数与作为匿名类型传入的对象匹配。
}否则{
//对这个错误做点什么
writeLink(string.Format(“{0}:{1}”,response.StatusCode.ToString(),response.ErrorMessage);
}
全面披露 这个库是一个免费的开源包装库,我是这个库的作者。我没有从中获利,但多年来发现它非常有用,我相信任何仍然使用HttpWebRequest/HttpWebResponse类的人也会这么做

它不是一个银弹,但支持get、post、delete以及异步和非异步get和post以及JSON或XML请求和响应。自2020年6月21日起,它正在积极维护中。您还可以使用它将HttpWebRequest和响应包装成简单的方法,根据结果返回对象。它使用一些这些答案中描述的技术,有大量的代码,灵感来自此线程和类似线程的答案。它自动捕获任何异常,寻求尽可能多地提取生成这些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);

    }
var response=httpClient.Get(请求);
if(response.StatusCode==HttpStatusCode.OK)
{
//对回应做点什么
console.Writeline(response.Body.Id);//其中Body参数与作为匿名类型传入的对象匹配。
}否则{
//对这个错误做点什么
writeLink(string.Format(“{0}:{1}”,response.StatusCode.ToString(),response.ErrorMessage);
}
全面披露 这个库是一个免费的开源包装库,我是这个库的作者。我没有从中获利,但多年来发现它非常有用,我相信任何仍然使用HttpWebRequest/HttpWebResponse类的人也会这么做

它不是一个银弹,但支持get、post、delete以及get和post as的异步和非异步