如何在C#代码中正确处理web响应中的UTF-8

本文关键字:web 响应 UTF-8 正确处理 代码 | 更新日期: 2023-09-27 18:29:42

在此之前,我从Joel Spolsky的文章中学到了关于文本编码的大部分知识。

我目前正在编写一个C#web系统,在我们的谷歌搜索设备上执行查询,读取结果并在我们自己的自定义UI中呈现给用户。但是,当我向用户显示文本摘要时,会出现编码问题。

当我直接在chrome/IE/whatever中查询GSA时,我得到以下响应

赛后笔记 8号种子德保罗。9种子美国橄榄球联合会第六场比赛-第二轮

在我的C#代码中,我正在阅读带有以下代码的响应:

        var request = WebRequest.Create(LastQueryUrl);
        var response = (HttpWebResponse)request.GetResponse();
        if (response.StatusCode != HttpStatusCode.OK)
            return null;
        using (var reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8))
            content = reader.ReadToEnd();

当我调试content变量时,我看到该字符串被转换为:

USF游戏6�第二个

我有99%的把握,来自GSA的数据是UTF-8格式的,因为它们的xml上的其他点以及文档中的各种花絮都表明了这一点。尽管如此,如果我使用System.Text.Encoding.Unicode读取流,则没有任何文本可读。

我做错了什么?如何才能正确显示文本?


编辑:使用System.Text.Encoding.GetEncoding("ISO-8859-1")给我

USF游戏6第二

没有问号,尽管破折号没有出现。

如何在C#代码中正确处理web响应中的UTF-8

您能尝试执行此代码(而不是using块)并再次粘贴结果吗?我假设你在.NET 4上。

using (var responseStream = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
    responseStream.CopyTo(memoryStream);
    byte[] bytes = memoryStream.ToArray();
    content = BitConverter.ToString(bytes);
}

编辑:我注意到你还没有在帖子中粘贴整个返回的字符串。是因为字符串的其余部分包含机密数据吗?如果是,请不要粘贴上面建议的结果。

编辑2:要使结果正确渲染,可以使用Encoding.GetEncoding(1252)然而,我建议你不要那样做,原因我很快就会解释

解释:根据我的估计,您的问题似乎是发送方的编码错误。你说他们的文档声称UTF-8,这显然与他们的ISO-8859-1 XML声明相矛盾。事实上,所使用的编码不是这两者。

在您上传的十六进制字符串中,罪魁祸首字符的字节值为0x96,出现在序列20-96-20的中间。在UTF-8和ISO-8859-1(以及之前的ASCII)中,0x20都是一个空格字符。但是,在UTF-8中,0x96是一个延续字节,除非前面有一个起始字节(而0x20不是),否则它是无效的。在ISO-8859-1中,0x96是C1控制字符,因此不是可打印字符(不能向用户显示)。

因此,我们可以推断,原始字符编码既不是UTF-8也不是ISO-8859-1,而是Windows-1252,有时被认为是ISO-8859-2的"超集",因为它用可显示的字符取代了0x800x9F范围的控制字符。事实上,在Windows-1252中,0x96是您所期望的短划线字符。

考虑到以上情况,通过假设Windows-1252编码来解决您的问题可能是安全的;但是,如果我是你,我会联系供应商并告知他们这个缺陷。

using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream, System.Text.Encoding.GetEncoding(1252)))
   content = reader.ReadToEnd();

HTML5规范要求广告为ISO-8859-1的文档实际上使用Windows-1252编码进行解析。