正在分析来自服务器的UTF8 JSON响应
本文关键字:UTF8 JSON 响应 服务器 | 更新日期: 2023-09-27 18:26:32
我在解析来自服务器的JSON响应时遇到了一个奇怪的问题。在过去的几个月里,当得到响应时,它一直工作得很好(内容类型: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...
但当收到内容类型为text/html的响应时;charset=utf8它抛出一个异常,即内容类型无效。
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);
现在我可以毫无例外地获得响应,但在解析它时,它会抛出解析异常。在调试过程中,我得到了以下信息:(出于测试目的,我将响应更改为较短的响应)
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"}
这个显然抛出了解析异常,但我不知道Encoding.UTF8.GetString
为什么会导致这种情况。
在过去的几个小时里,我一直在与之斗争,我真的需要一些帮助。
好吧,我很惊讶你会有这种行为,我本以为Encoding.UTF8.GetString
会帮你处理的。
您看到的字符值0xFEFF
是一个字节顺序标记("BOM")。BOM在UTF-8中是不必要的,因为字节顺序不是可变的,但它是允许的,因为它标记了以下文本是UTF-8编码的。(实际的字节序列是EF BB BF,但当以UTF-8解码时,它就变成了代码点FEFF。)
如果创建自己的
(我想我错了,它可能只控制在编码时是否包括一个。)UTF8Encoding
实例,则可以告诉它是包含BOM表还是排除BOM表
或者,您可以明确测试并删除BOM(如果存在),例如:
var r2 = Encoding.UTF8.GetString(await clientResult.Content.ReadAsByteArrayAsync(), 0, raw_response.Length);
if (r2[0] == ''uFEFF') {
r2 = r2.Substring(1);
}