如何在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第二
没有问号,尽管破折号没有出现。
您能尝试执行此代码(而不是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的"超集",因为它用可显示的字符取代了0x80
–0x9F
范围的控制字符。事实上,在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
编码进行解析。