我的客户遇到了一个问题,但在使用相同的应用程序版本和数据时,任何开发人员都不会遇到此问题。
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 string
实例中使用了有效的JSON,我们使用UTF8.GetBytes
对其进行转换,但当DataContractJsonSerializer.ReadObject
读取它时,我们会发现损坏。
知道为什么会这样吗?为什么它出现在某些机器而不是其他机器上?
答案 0 :(得分:1)
这是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);
}
这些开发者机器都没有抛出异常,但是我们的客户'电脑可以。
修复方法是使用缓冲的JSON阅读器而不是MemoryStream
:
using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(result, XmlDictionaryReaderQuotas.Max))
{
var outputSerialiser = new DataContractJsonSerializer(typeof(string));
string output = (string) outputSerialiser.ReadObject(jsonReader);
}