首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从ResponseStream获得WebException

无法从ResponseStream获得WebException
EN

Stack Overflow用户
提问于 2015-02-04 09:06:58
回答 2查看 2.4K关注 0票数 2

我有一个桌面客户端,通过Http与服务器端进行通信。当服务器在数据处理中遇到一些问题时,它会用正确的Http代码(主要是HTTP-400)返回HTTP响应体中JSON错误的描述。

当我阅读HTTP-200响应时,一切都很好,并且这段代码可以工作:

代码语言:javascript
复制
 using (var response = await httpRequest.GetResponseAsync(token))
                {
                    using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
                    {
                        return await reader.ReadToEndAsync();
                    }
                }

但是,当发生错误并引发和捕获WebException时,有以下代码:

代码语言:javascript
复制
 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 (它是"") --我甚至不知道该在哪里查找,因为看起来它应该能工作。

有什么问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-10 08:41:37

经过一个月的日常思考,我找到了解决办法。

问题是,WebException.Response.GetResponseStream()返回的流与请求期间获得的流不完全相同(现在无法找到指向msdn的链接),当我们捕获异常并读取该流时,实际的响应流就丢失了(或者类似的内容,除了查看现在是开放资源的CLRCore之外,还无法在网络上找到任何信息)。

要保存实际的响应直到捕获WebException,必须在HttpRequest和瞧中设置KeepAlive属性,在捕获异常时得到响应。工作代码看起来是这样的:

代码语言:javascript
复制
            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

票数 5
EN

Stack Overflow用户

发布于 2015-02-05 08:09:49

我记得我以前也遇到过类似的问题,还有一些与确定溪流的立场有关的事情。Here is one of my solutions,因为我之前读过webResponse。如果类似的方法对您有效,请尝试:-

代码语言:javascript
复制
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);
//......
//.......

希望这能有所帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28317386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档