c# - 解析来自服务器的 UTF8 JSON 响应

标签 c# .net json http utf-8

我在解析来 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/

相关文章:

c# - 解决数独中的裸三元组

c# - SqlBulkCopy 无法将值 NULL 插入到列中

javascript - 一个 javascript 类,它接受 JSON 对象并将其转换为属性 property

javascript - 我应该使用 JSON 还是 AJAX 作为响应数据?

c# - 现有类(class)的精简版

c# - 库文件夹封面照片使用 C#

C# 传递一个值到一个新的表单

c# - DataColumn 插入列表(相同数据类型)

javascript - 将输入值推送到本地存储中的数组出错

c# - ASP.NET 每小时更新一次数据库