我有一个问题发生在我们的客户身上,但在使用相同的应用程序版本和数据时不会发生在任何开发人员身上。DataContractJsonSerializer.ReadObject
抛出这个异常:
Deserialising: There was an error deserializing the object of type {type}.
The token '"' was expected but found 'Â'.
当任何开发人员或我试图重现它时,不会抛出此异常,而是始终在客户端系统上发生。每个人都在使用 Windows 7 64 位。
我最好的猜测是这是一个文本编码问题,作为
0xC2,0x??
的 UTF-8 字节对最终会变成 Â
如果转换为 Windows 1252 或 ISO 8859-1。到 UTF-8 的转换是在代码中完成的:
string content = GetSerialised();
byte[] result = Encoding.UTF8.GetBytes(content);
using (var s = new MemoryStream(result))
{
var outputSerialiser = new DataContractJsonSerializer(typeof(T), null, int.MaxValue, true, null, false);
return (T) outputSerialiser.ReadObject(s);
}
content
与错误消息一起显示,因此我们能够验证它是有效的 JSON 文本。它确实包含一个 ¦
在 JSON 字符串中引用(即 UTF-8 中的 0xC2,0xA6
,因此可能是损坏字符的罪魁祸首)。所以我们在 .Net 中有有效的 JSON
string
例如,我们使用 UTF8.GetBytes
转换它,但是当 DataContractJsonSerializer.ReadObject
读它我们得到一个腐败。知道为什么会这样吗?为什么它发生在某些机器上而不是其他机器上?
最佳答案
这是due to a bug in the DataContractJsonSerializer.ReadObject(Stream)
method这已在 .Net 4.0 的补丁中修复 - 开发人员有补丁但我们的用户没有,这就是我们没有得到它的原因。
如果单个序列化对象中有大量非 ANSI 字符,则会出现该错误。
我写了一个简单的应用程序来检查这个问题:
// Create a JSON string with more non-ANSI characters than can be handled
char test = (char) 0x6cd5;
string content = "\"" + new string(test, 2048) + "\"";
// Use a MemoryStream
byte[] result = Encoding.UTF8.GetBytes(content);
using (var s = new MemoryStream(result))
{
var outputSerialiser = new DataContractJsonSerializer(typeof(string));
// This line will throw the exception
string output = (string) outputSerialiser.ReadObject(s);
}
没有任何开发机器在这里抛出异常,但我们客户的 PC 会抛出异常。
修复方法是使用缓冲的 JSON 读取器而不是
MemoryStream
:using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(result, XmlDictionaryReaderQuotas.Max))
{
var outputSerialiser = new DataContractJsonSerializer(typeof(string));
string output = (string) outputSerialiser.ReadObject(jsonReader);
}
关于.net - DataContractJsonSerializer.ReadObject 有时会抛出 : The token "was expected but found ' Â',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23909231/