C# REST API响应中的前导unicode字符导致Xml异常
当我试图解析来自某个REST API的响应时,我得到一个C# REST API响应中的前导unicode字符导致Xml异常,c#,xml,unicode,C#,Xml,Unicode,当我试图解析来自某个REST API的响应时,我得到一个XmlException说“根级别的数据无效。第1行,位置1”。查看XML看起来不错,但检查第一个字符时,我发现它实际上是一个字符(字符代码65279或0xFEFF) 有什么好的理由让那个角色出现吗?也许我应该在发出请求时设置不同的编码?目前我正在使用编码.UTF8 我考虑过从字符串中删除该字符,或者要求RESTAPI的开发人员修复它,但在执行这些操作之前,我想检查该字符是否存在有效的原因。我不是unicode专家。我应该做些不同的事情吗
XmlException
说“根级别的数据无效。第1行,位置1”。查看XML看起来不错,但检查第一个字符时,我发现它实际上是一个字符(字符代码65279或0xFEFF)
有什么好的理由让那个角色出现吗?也许我应该在发出请求时设置不同的编码?目前我正在使用编码.UTF8
我考虑过从字符串中删除该字符,或者要求RESTAPI的开发人员修复它,但在执行这些操作之前,我想检查该字符是否存在有效的原因。我不是unicode专家。我应该做些不同的事情吗
编辑:我怀疑可能是这样的(BOM)。所以,问题变成了,我应该特别处理这个角色吗?我尝试了两种方式加载XML,但都引发了相同的异常:
public static User GetUser()
{
WebClient req = new WebClient();
req.Encoding = Encoding.UTF8;
string response = req.DownloadString(url);
XmlSerializer ser = new XmlSerializer(typeof(User));
User user = ser.Deserialize(new StringReader(response)) as User;
XElement xUser = XElement.Parse(response);
...
return user;
}
U+FFEF是一个很好的例子。它位于文档的开头,用于指示字符编码(或者更确切地说,编码的字节顺序,可以是任意一种方式;最具体的是UTF-16)。它在XML文档的开头出现是完全合理的。不推荐将其用作零宽度非中断空间,而支持U+2060
如果字节顺序标记采用不同的编码,例如,如果它是声称为UTF-8的文档中的UTF-8 BOM,则这是不合理的
您是如何加载文档的?也许您在某个地方指定了不适当的编码?如果可能的话,最好让XMLAPI检测编码
编辑:当你把它作为一个字符串下载后,我可以想象这会引起问题。。。假设它是用来检测编码的,你已经知道了。不要将其作为字符串下载-将其作为二进制数据下载(WebClient.DownloadData
),然后您应该可以解析它了,我相信。但是,您可能仍然不应该使用XElement.Parse
,因为可能存在文档声明-使用XDocument.Parse
。如果调用的结果可以直接输入到XmlSerializer
,我会有点惊讶,但您可以尝试。。。如有必要,将其包装在一个内存流中。U+FFEF是一个。它位于文档的开头,用于指示字符编码(或者更确切地说,编码的字节顺序,可以是任意一种方式;最具体的是UTF-16)。它在XML文档的开头出现是完全合理的。不推荐将其用作零宽度非中断空间,而支持U+2060
如果字节顺序标记采用不同的编码,例如,如果它是声称为UTF-8的文档中的UTF-8 BOM,则这是不合理的
您是如何加载文档的?也许您在某个地方指定了不适当的编码?如果可能的话,最好让XMLAPI检测编码
编辑:当你把它作为一个字符串下载后,我可以想象这会引起问题。。。假设它是用来检测编码的,你已经知道了。不要将其作为字符串下载-将其作为二进制数据下载(WebClient.DownloadData
),然后您应该可以解析它了,我相信。但是,您可能仍然不应该使用XElement.Parse
,因为可能存在文档声明-使用XDocument.Parse
。如果调用的结果可以直接输入到XmlSerializer
,我会有点惊讶,但您可以尝试。。。如有必要,将其包装在内存流中。开头的字符是BOM(字节顺序标记)。它作为unicode文本文件中的第一个字符放置,以指定用于创建文件的编码
BOM不应该是响应的一部分,因为HTTP内容的编码方式不同
通常,响应中的BOM来自发送文本文件作为响应,其中文本文件与BOM签名一起保存。例如,Visual Studio有一个选项,可以保存不带BOM签名的文件,以便直接作为响应发送。开头的字符是BOM(字节顺序标记)。它作为unicode文本文件中的第一个字符放置,以指定用于创建文件的编码
BOM不应该是响应的一部分,因为HTTP内容的编码方式不同
通常,响应中的BOM来自发送文本文件作为响应,其中文本文件与BOM签名一起保存。例如,VisualStudio有一个选项,可以保存一个没有BOM签名的文件,这样就可以直接将其作为响应发送。这就是所谓的。但在UTF-8中不需要它。这称为a。但是UTF-8中不需要它。不要使用编码。UTF8,使用构造函数重载创建自己的UTF-8编码器,该重载允许您指定是否要发出BOM表:
req.Encoding = new UTF8Encoding( false ) ; // omit the BOM
我相信这会对你有好处
修改为注释:以下各项将起作用:
不要使用Encoding.UTF8,而是使用构造函数重载创建自己的UTF-8编码器,该重载允许您指定是否要发出BOM表:
req.Encoding = new UTF8Encoding( false ) ; // omit the BOM
我相信这会对你有好处
修改为注释:以下各项将起作用:
我使用的是XmlSerializer
和XElement.Parse()
。请参阅对我的问题的编辑。我正在使用XmlSerializer
和XElement.Parse()
。请参阅对我的问题的编辑。遗憾的是,这不起作用。我仍然收到一个U+FFEF作为req.DownloadString()
返回的第一个字符,并且仍然抛出XmlException
。@gilly3:有关解决方案,请参阅我的修订答案