从服务器解析UTF8 JSON响应

我正面临一个从我的服务器解析JSON响应的奇怪问题。 在过去几个月这种方式获得响应(使用Content-Type:text / html)时,它一直运行良好:

string response = ""; using (var client = new System.Net.Http.HttpClient()) { var postData = new System.Net.Http.FormUrlEncodedContent(data); var clientResult = await client.PostAsync(url, postData); if(clientResult.IsSuccessStatusCode) { response = await clientResult.Content.ReadAsStringAsync(); } } //Parse the response to a JObject... 

但是当收到Content-Type:text / html的回复时; charset = utf8会抛出Content-Type无效的exception。

Exception message: The character set provided in ContentType is invalid. Cannot read content as string using an invalid character set.

所以我改变了这个:

 response = await clientResult.Content.ReadAsStringAsync(); 

对此:

 var raw_response = await clientResult.Content.ReadAsByteArrayAsync(); response = Encoding.UTF8.GetString(raw_response, 0, raw_response.Length); 

现在我可以在没有exception的情况下获得响应,但在解析它时,它会抛出一个解析exception。 调试时我得到了这个:(为了测试目的,我将响应更改为较短的响应)

 var r1 = await clientResult.Content.ReadAsStringAsync(); var r2 = Encoding.UTF8.GetString(await clientResult.Content.ReadAsByteArrayAsync(), 0, raw_response.Length); System.Diagnostics.Debug.WriteLine("Length: {0} - {1}", r1.Length, r1); System.Diagnostics.Debug.WriteLine("Length: {0} - {1}", r2.Length, r2); //Output Length: 38 - {"version":1,"specialword":"C\u00e3o"} Length: 39 - {"version":1,"specialword":"C\u00e3o"} 

JSON响应格式在两种情况下都是正确的,但长度不同,我无法弄清楚原因。 将此复制到记事本++以识别隐藏字符时 无处不在。

 Length: 38 - {"version":1,"specialword":"C\u00e3o"} Length: 39 - ?{"version":1,"specialword":"C\u00e3o"} 

这个 显然是抛出解析exception,但我不知道为什么Encoding.UTF8.GetString导致了这种情况。

在过去的几个小时里,我一直在与这个斗争,我真的需要一些帮助。

好吧,我很惊讶你得到了这种行为,我本以为Encoding.UTF8.GetString已经为你处理过了。

您所看到的,字符值0xFEFF是字节顺序标记(“BOM”)。 在UTF-8中不需要BOM,因为字节顺序不是可变的,但是允许它作为以下文本编码为UTF-8的标记。 (实际的字节序列是EF BB BF,但是当它以UTF-8解码时,它变为代码点FEFF。)

如果您创建自己的UTF8Encoding实例 ,则可以告诉它是包含还是排除BOM。 (我想我错了,它可能只控制它在编码时是否包含一个 。)

或者,您可以明确地测试并删除BOM(如果存在),例如:

 var r2 = Encoding.UTF8.GetString(await clientResult.Content.ReadAsByteArrayAsync(), 0, raw_response.Length); if (r2[0] == '\uFEFF') { r2 = r2.Substring(1); }