我在解析来 self 的服务器的 JSON 响应时遇到了一个奇怪的问题。在过去的几个月里,它以这种方式获得响应 (with 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 无效。
异常消息:ContentType 中提供的字符集无效。无法使用无效字符集将内容读取为字符串。
所以我改变了这个:
response = await clientResult.Content.ReadAsStringAsync();
为此:
var raw_response = await clientResult.Content.ReadAsByteArrayAsync();
response = Encoding.UTF8.GetString(raw_response, 0, raw_response.Length);
现在我可以毫无异常(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 响应格式在这两种情况下似乎都是正确的,但长度不同,我不明白为什么。当将此复制到 Notepad++ 以发现隐藏字符时,? 不知从何处出现。
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
instance ,你可以告诉它是否包含或排除BOM。
或者,您可以显式测试它并删除 BOM(如果存在),例如:
var r2 = Encoding.UTF8.GetString(await clientResult.Content.ReadAsByteArrayAsync(), 0, raw_response.Length);
if (r2[0] == '\uFEFF') {
r2 = r2.Substring(1);
}
关于c# - 解析来自服务器的 UTF8 JSON 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18043128/