无法从 WebException 获取 ResponseStream
Can't get ResponseStream from WebException
我有一个桌面客户端,它通过 Http 与服务器端通信。
当服务器在处理数据时遇到一些问题 returns 在具有正确的 Http 代码(主要是 HTTP-400)的 Http 响应正文中 JSON 中描述错误。
当我读取 HTTP-200 响应时一切正常并且此代码有效:
using (var response = await httpRequest.GetResponseAsync(token))
{
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
return await reader.ReadToEndAsync();
}
}
但是当发生错误并抛出并捕获 WebException 时,有以下代码:
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
using (var response = (HttpWebResponse) ex.Response)
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream, Encoding.GetEncoding("utf-8")))
{
var json = reader.ReadToEnd();
}
}
}
}
}
我已经对其进行了一些处理,也许可以让它正常工作,但接下来会发生:
response.ContentLength
有效 (184)
但是 stream.Length
是 0
之后我无法阅读 json(它是 ""
)
我什至不知道去哪里看,因为一切看起来都应该有效。
可能是什么问题?
我记得以前遇到过类似的问题,并且与设置流的位置有关。 Here is one of my solutions 用于阅读之前对我有用的 webResponse。请尝试类似的方法是否适合您:-
private ResourceResponse readWebResponse(HttpWebRequest webreq)
{
HttpWebRequest.DefaultMaximumErrorResponseLength = 1048576;
HttpWebResponse webresp = null;// = webreq.GetResponse() as HttpWebResponse;
var memStream = new MemoryStream();
Stream webStream;
try
{
webresp = (HttpWebResponse)webreq.GetResponse();
webStream = webresp.GetResponseStream();
byte[] readBuffer = new byte[4096];
int bytesRead;
while ((bytesRead = webStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
memStream.Write(readBuffer, 0, bytesRead);
}
catch (WebException e)
{
var r = e.Response as HttpWebResponse;
webStream = r.GetResponseStream();
memStream = Read(webStream);
var wrongLength = memStream.Length;
}
memStream.Position = 0;
StreamReader sr = new StreamReader(memStream);
string webStreamContent = sr.ReadToEnd();
byte[] responseBuffer = Encoding.UTF8.GetBytes(webStreamContent);
//......
//.......
希望对您有所帮助!
经过一个月几乎每天都在思考,我找到了解决方法。
问题是 WebException.Response.GetResponseStream()
returns 与请求期间获得的流不完全相同(现在无法在 msdn 上找到 link),到我们得到的时候要捕获异常并读取此流,实际响应流会丢失(或类似的东西,真的不知道并且无法在网上找到任何信息,除了查看现在开源的 CLRCore)。
要在捕获 WebException
之前保存实际响应,您必须在 HttpRequest
上设置 KeepAlive
属性 瞧,您在捕获异常时会得到响应。
所以工作代码看起来像这样:
try
{
var httpRequest = WebRequest.CreateHttp(Protocol + ServerUrl + ":" + ServerPort + ServerAppName + url);
if (HttpWebRequest.DefaultMaximumErrorResponseLength < int.MaxValue)
HttpWebRequest.DefaultMaximumErrorResponseLength = int.MaxValue;
httpRequest.ContentType = "application/json";
httpRequest.Method = method;
var encoding = Encoding.GetEncoding("utf-8");
if (httpRequest.ServicePoint != null)
{
httpRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
httpRequest.ServicePoint.MaxIdleTime = 5000;
}
//----HERE--
httpRequest.KeepAlive = true;
//----------
using (var response = await httpRequest.GetResponseAsync(token))
{
using (var reader = new StreamReader(response.GetResponseStream(), encoding))
{
return await reader.ReadToEndAsync();
}
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
using (var response = (HttpWebResponse)ex.Response)
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream, Encoding.GetEncoding("utf-8")))
{
return reader.ReadToEnd();
//or handle it like you want
}
}
}
}
}
我不知道像那样保持所有连接是否有效,但由于它帮助我读取来自服务器的实际响应,我认为它可能对遇到同样问题的人有所帮助。
编辑:同样重要的是不要弄乱 HttpWebRequest.DefaultMaximumErrorResponseLength
。
我有一个桌面客户端,它通过 Http 与服务器端通信。 当服务器在处理数据时遇到一些问题 returns 在具有正确的 Http 代码(主要是 HTTP-400)的 Http 响应正文中 JSON 中描述错误。
当我读取 HTTP-200 响应时一切正常并且此代码有效:
using (var response = await httpRequest.GetResponseAsync(token))
{
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
return await reader.ReadToEndAsync();
}
}
但是当发生错误并抛出并捕获 WebException 时,有以下代码:
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
using (var response = (HttpWebResponse) ex.Response)
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream, Encoding.GetEncoding("utf-8")))
{
var json = reader.ReadToEnd();
}
}
}
}
}
我已经对其进行了一些处理,也许可以让它正常工作,但接下来会发生:
response.ContentLength
有效 (184)
但是 stream.Length
是 0
之后我无法阅读 json(它是 ""
)
我什至不知道去哪里看,因为一切看起来都应该有效。
可能是什么问题?
我记得以前遇到过类似的问题,并且与设置流的位置有关。 Here is one of my solutions 用于阅读之前对我有用的 webResponse。请尝试类似的方法是否适合您:-
private ResourceResponse readWebResponse(HttpWebRequest webreq)
{
HttpWebRequest.DefaultMaximumErrorResponseLength = 1048576;
HttpWebResponse webresp = null;// = webreq.GetResponse() as HttpWebResponse;
var memStream = new MemoryStream();
Stream webStream;
try
{
webresp = (HttpWebResponse)webreq.GetResponse();
webStream = webresp.GetResponseStream();
byte[] readBuffer = new byte[4096];
int bytesRead;
while ((bytesRead = webStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
memStream.Write(readBuffer, 0, bytesRead);
}
catch (WebException e)
{
var r = e.Response as HttpWebResponse;
webStream = r.GetResponseStream();
memStream = Read(webStream);
var wrongLength = memStream.Length;
}
memStream.Position = 0;
StreamReader sr = new StreamReader(memStream);
string webStreamContent = sr.ReadToEnd();
byte[] responseBuffer = Encoding.UTF8.GetBytes(webStreamContent);
//......
//.......
希望对您有所帮助!
经过一个月几乎每天都在思考,我找到了解决方法。
问题是 WebException.Response.GetResponseStream()
returns 与请求期间获得的流不完全相同(现在无法在 msdn 上找到 link),到我们得到的时候要捕获异常并读取此流,实际响应流会丢失(或类似的东西,真的不知道并且无法在网上找到任何信息,除了查看现在开源的 CLRCore)。
要在捕获 WebException
之前保存实际响应,您必须在 HttpRequest
上设置 KeepAlive
属性 瞧,您在捕获异常时会得到响应。
所以工作代码看起来像这样:
try
{
var httpRequest = WebRequest.CreateHttp(Protocol + ServerUrl + ":" + ServerPort + ServerAppName + url);
if (HttpWebRequest.DefaultMaximumErrorResponseLength < int.MaxValue)
HttpWebRequest.DefaultMaximumErrorResponseLength = int.MaxValue;
httpRequest.ContentType = "application/json";
httpRequest.Method = method;
var encoding = Encoding.GetEncoding("utf-8");
if (httpRequest.ServicePoint != null)
{
httpRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
httpRequest.ServicePoint.MaxIdleTime = 5000;
}
//----HERE--
httpRequest.KeepAlive = true;
//----------
using (var response = await httpRequest.GetResponseAsync(token))
{
using (var reader = new StreamReader(response.GetResponseStream(), encoding))
{
return await reader.ReadToEndAsync();
}
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
using (var response = (HttpWebResponse)ex.Response)
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream, Encoding.GetEncoding("utf-8")))
{
return reader.ReadToEnd();
//or handle it like you want
}
}
}
}
}
我不知道像那样保持所有连接是否有效,但由于它帮助我读取来自服务器的实际响应,我认为它可能对遇到同样问题的人有所帮助。
编辑:同样重要的是不要弄乱 HttpWebRequest.DefaultMaximumErrorResponseLength
。