DataContractJson反序列化报错:遇到意外字符'D',求问题排查
问题分析:反序列化JSON时遇到意外字符'D'
错误信息
反序列化类型为Tutorial10.DataContractJsonExample.Customer的对象时出错,遇到意外字符'D'。
代码示例
internal class DataContractJsonSerialization { public static void Run() { Customer customer = new Customer() { Name = "Sas", Age = 21, Email = "email@email.com", Weight = 75.4, IsAlive = true, Orders = new Order[] { new Order() { Price = 400, Name = "Cake" }, new Order() { Price = 20.5, Name = "Apple" } } }; WriteObject("DataContractJsonSerialization.json", customer); ReadObject("DataContractJsonSerialization.json"); } public static void WriteObject(string fileName, Customer customer) { FileStream writer = new FileStream(fileName, FileMode.Create); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Customer)); ser.WriteObject(writer, customer); writer.Close(); } public static void ReadObject(string fileName) { var deserializedUser = new Customer(); var ms = new MemoryStream(Encoding.UTF8.GetBytes(fileName)); var ser = new DataContractJsonSerializer(deserializedUser.GetType()); deserializedUser = ser.ReadObject(ms) as Customer; ms.Close(); } }
问题根源
问题出在ReadObject方法里:你把文件名字符串直接转换成字节流传给了MemoryStream,而不是读取文件中实际的JSON内容。文件名"DataContractJsonSerialization.json"的第一个字符是'D',反序列化器误以为这是JSON数据的开头,自然会抛出"遇到意外字符'D'"的错误。
修复方案
修改ReadObject方法,读取文件的实际内容而非文件名:
方案一:使用FileStream直接读取文件
public static void ReadObject(string fileName) { var deserializedUser = new Customer(); // 用FileStream打开文件读取内容 using (var fs = new FileStream(fileName, FileMode.Open)) { var ser = new DataContractJsonSerializer(deserializedUser.GetType()); deserializedUser = ser.ReadObject(fs) as Customer; } }
方案二:读取文件字节数组到MemoryStream
public static void ReadObject(string fileName) { var deserializedUser = new Customer(); // 先读取文件的全部字节 byte[] jsonContent = File.ReadAllBytes(fileName); using (var ms = new MemoryStream(jsonContent)) { var ser = new DataContractJsonSerializer(deserializedUser.GetType()); deserializedUser = ser.ReadObject(ms) as Customer; } }
额外优化建议
建议使用using语句管理流资源,它会自动释放资源,避免手动调用Close()可能导致的资源泄漏,比如把序列化的WriteObject方法也改成更规范的写法:
public static void WriteObject(string fileName, Customer customer) { using (FileStream writer = new FileStream(fileName, FileMode.Create)) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Customer)); ser.WriteObject(writer, customer); } }
内容的提问来源于stack exchange,提问作者NoOneCare
相关产品推荐
相关产品推荐

