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

C# 如何在我的C代码中正确处理web响应中的UTF-8?,c#,character-encoding,C#,Character Encoding,作为前言,我从这篇文章中学到了关于文本编码的大部分知识 我目前正在编写一个C#web系统,在我们的Google搜索设备上执行查询,读取结果,并在我们自己的自定义UI中将其呈现给用户。但是,在向用户显示文本摘要时存在编码问题 当我直接在chrome/IE/whatever中查询GSA时,我得到以下响应 赛后笔记8号种子德保与9号种子USF第6场-第二轮 在我的C#代码中,我用以下代码阅读该响应: var request = WebRequest.Create(LastQueryUr

作为前言,我从这篇文章中学到了关于文本编码的大部分知识

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

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

赛后笔记8号种子德保与9号种子USF第6场-第二轮

在我的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();
调试
内容
变量时,我看到该字符串转换为:

USF第6场� 第二

我99%确信来自GSA的数据是UTF-8格式的,因为他们的xml上有其他点这样说,以及文档中的各种花絮。即使如此,如果我使用
System.Text.Encoding.Unicode
读取流,则所有文本都不可读

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


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

USF第6场比赛秒


没有问号,尽管破折号没有显示。

您可以尝试执行此代码(而不是使用
块)并再次粘贴结果吗?我假设你在.NET4上

using (var responseStream = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
    responseStream.CopyTo(memoryStream);
    byte[] bytes = memoryStream.ToArray();
    content = BitConverter.ToString(bytes);
}
编辑:我注意到您没有在帖子中粘贴整个返回字符串。是因为字符串的其余部分包含机密数据吗?如果是,请不要粘贴上面建议的结果

Edit2:要正确渲染结果,可以使用
Encoding.GetEncoding(1252)
;不过,我建议你不要这样做,原因我会很快解释

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

在你上传的十六进制字符串中,罪犯角色的字节值为“代码>0x96”,并出现在序列<代码> -209620的中间。在UTF-8和ISO-8859-1(以及之前的ASCII)中,
0x20
是一个空格字符。但是,在中,
0x96
是一个连续字节,除非前面有一个开始字节(而
0x20
不是)。在中,
0x96
是C1控制字符,因此不是可打印字符(无法向用户显示)

因此,我们可以推断原始字符编码既不是UTF-8也不是ISO-8859-1,但有时被认为是ISO-8859-1的“超集”,因为它用可显示字符替换了控制字符的
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
编码进行解析

您的代码似乎是正确的。为了帮助我们确定您的问题,您是否可以暂时将您的编码替换为
System.Text.encoding.GetEncoding(“ISO-8859-1”)
,并将呈现的字符串粘贴到此处?我建议ISO-8859-1(拉丁语-1)的原因是,即使它与您的文本的原始编码不匹配,它仍然提供了所有256字节值和一个字符之间的一对一映射,从而允许我们推断您实际接收到的字节值。它有帮助,但还不是100%。查看
响应的内容。ContentEncoding
,它真的是utf-8吗?响应。根据VS的调试器,ContentEncoding是空白的,但contentType是“text/xml;charset=ISO-8859-1”,它太大了,无法粘贴,因此我将结果上载到No,出于简洁的考虑,我只粘贴了上面的相关部分。它是由20个搜索结果组成的XML,所有这些结果都将显示给公众用户;给我几分钟,我会给你回电的。@KallDrexx-这个例子行得通吗,但不是使用
BitConverter.ToString(bytes)
,而是使用
Encoding.UTF8.GetString(bytes)?@swDevMan81:这导致了上面描述的原始问题(带有问号),这使它更有意义