C# DownloadString和HttpWebResponse未返回完整的JSON内容

C# DownloadString和HttpWebResponse未返回完整的JSON内容,c#,.net,httpwebrequest,webclient,httpwebresponse,C#,.net,Httpwebrequest,Webclient,Httpwebresponse,我正在尝试将来自以下内容的JSON响应存储在字符串中。大多数情况下,我运行代码时,JSON响应的最后几个字符被截断。在浏览器中访问url时,会显示完整的JSON响应。有时我的代码可以工作,但大多数时候它返回部分内容 如果我减少我请求的url中查询的长度,我会得到更多的内容,更接近完整的响应,这是非常奇怪的。如果我完全删除querystring,通常会返回完整的JSON响应。问题是我确实想保持查询字符串的原样 我尝试了各种选择,包括更改编码、使用HttpWebRequest/HttpWebResp

我正在尝试将来自以下内容的JSON响应存储在字符串中。大多数情况下,我运行代码时,JSON响应的最后几个字符被截断。在浏览器中访问url时,会显示完整的JSON响应。有时我的代码可以工作,但大多数时候它返回部分内容

如果我减少我请求的url中查询的长度,我会得到更多的内容,更接近完整的响应,这是非常奇怪的。如果我完全删除querystring,通常会返回完整的JSON响应。问题是我确实想保持查询字符串的原样

我尝试了各种选择,包括更改编码、使用HttpWebRequest/HttpWebResponse、使用

关于如何得到充分的回应,以及如何解释正在发生的事情,你有什么想法吗?谢谢

System.Net.WebClient wc = new System.Net.WebClient();            
string data = wc.DownloadString("http://static.arcgis.com/attribution/World_Topo_Map?f=json&callback=dojo.io.script.jsonp_dojoIoScript19._jsonpCallback");
Console.Write(data);// String should end with ",-119.2]}]}]});"
Console.Read();

我使用您的代码进行了测试,该代码工作正常

p、 当您仅用于解析json时,不需要
&callback
参数。(javascript上的jsonp回调需要回调参数)


这是一个服务器问题,但幸运的是,我相信有一个解决办法。服务器未返回正确的未压缩结果。如果您更改客户端代码以接受压缩响应,那么问题似乎就消失了

不清楚的是为什么未压缩的响应会被破坏。服务器可能在超过64K的响应中遇到问题(此json为64.8K)。服务器可能在其长度计算中存在缺陷,该缺陷仅在某些情况下或某些地图中出现。我不确定。因此,不能保证压缩解决方案在所有情况下都能工作,我建议您在这方面进行测试。跟踪ArcGIS人员,让他们知道这个错误

下面是我用来返回正确JSON的解压缩代码(改编自)

public class GZipWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        return request;
    }
}

GZipWebClient wc = new GZipWebClient();
string data = wc.DownloadString("http://static.arcgis.com/attribution/World_Topo_Map?f=json&callback=dojo.io.script.jsonp_dojoIoScript19._jsonpCallback");
以下是我如何发现这种解决方法的:

  • 首先,我用代码重现了这个问题
  • 然后,我将请求更改为HTTP 1.0(它不包含或压缩),并注意到服务器返回的
    Content-Length
    头是
    66338
    。但实际内容比这要长。因此,服务器告诉客户端内容比实际长度短,这就解释了WebClient响应被截断的原因
  • 然后,我尝试用客户端手动处理分块编码,但没有成功——我得到了相同的截断
  • 在这一点上,我想知道这是否是一个绝对长度问题,例如,服务器处理的响应较短,但低估了较长响应的长度
  • 因此,我经常处理请求头,我发现删除压缩头(
    Accept-Encoding:gzip、deflate、sdch
    )会重现问题
  • 这解释了为什么此请求在浏览器(使用压缩)中工作,而不在代码中工作
  • 所以我尝试了一个支持压缩的C#客户端,一切正常
不幸的是,这并没有告诉您根本原因,因此压缩解决方案可能在所有情况下都会起作用,也可能不会。它可能会在较长的响应时间内中断。它可能会在不同的地图上断裂。测试它以确保

它也不能解释为什么@ssut无法重新编程。可能只有ArgGIS集群中的某些服务器易受攻击?我不知道

顺便说一句,如果您想向ArcGIS报告错误,这里有一个HTTP请求,他们可以使用它来重新处理问题:

GET http://static.arcgis.com/attribution/World_Topo_Map?f=json&callback=dojo.io.script.jsonp_dojoIoScript19._jsonpCallback HTTP/1.0
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: static.arcgis.com

留下答案是因为我没有足够的声誉对你的答案留下评论


我认为这是mono客户端的一个bug,而不是服务器bug。我在我使用的一些代码中跟踪到了这一点。它可以在使用.Net的Windows上完美运行。它只在使用mono运行代码时失败。当我使用GZipWebClient时,它也能在mono上完美运行。

谢谢,我处理的代码库要求传递回调参数。也许有办法解决这个问题,所以我不会排除这个可能性。你是如何运行C#on的mac@Gupta我用过和Xamarin工作室。如果在mac电脑上安装了自制软件,您可以使用
brew安装mono
@Nice,我在Windows上:)安装mono,这是一个很棒的答案!我验证了压缩解决方案的有效性!谢谢你的帮助!