DataContractJsonSerializer不适用于格式化的JSON?

当使用DataContractJsonSerializer反序列化JSON时,如果输入中有选项卡(格式化JSON),则序列化程序会抛出exception(如下所示)。 如果我用“”替换所有空格,制表符和换行符,则序列化程序可以很好地反序列化它。

这是怎么回事?

例外

 System.MemberAccessException: Cannot create an abstract class. at System.Runtime.Serialization.FormatterServices.nativeGetUninitializedObject(RuntimeType type) at System.Runtime.Serialization.FormatterServices.GetUninitializedObject(Type type) at System.Runtime.Serialization.XmlFormatReaderGenerator.UnsafeGetUninitializedObject(Int32 id) at ReadBaseSearchElementFromJson(XmlReaderDelegator , XmlObjectSerializerReadContextComplexJson , XmlDictionaryString , XmlDictionaryString[] ) at System.Runtime.Serialization.Json.JsonClassDataContract.ReadJsonValueCore(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context) at System.Runtime.Serialization.Json.JsonDataContract.ReadJsonValue(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context) at System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader) at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract) at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, String name, String ns) at ReadSearchElementsFromJson(XmlReaderDelegator , XmlObjectSerializerReadContextComplexJson , XmlDictionaryString , XmlDictionaryString , CollectionDataContract ) at System.Runtime.Serialization.Json.JsonCollectionDataContract.ReadJsonValueCore(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context) at System.Runtime.Serialization.Json.JsonDataContract.ReadJsonValue(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context) at System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader) at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract) at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, String name, String ns) at ReadSearchGroupFromJson(XmlReaderDelegator , XmlObjectSerializerReadContextComplexJson , XmlDictionaryString , XmlDictionaryString[] ) at System.Runtime.Serialization.Json.JsonClassDataContract.ReadJsonValueCore(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context) at System.Runtime.Serialization.Json.JsonDataContract.ReadJsonValue(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context) at System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader) at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract) at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns) at System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName) at System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader) at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(Stream stream) 

格式化的JSON

不会反序列化,抛出上面的exception。

 { "Mode":"And", "Elements": [ { "Name":"ID", "Operator":"Equal", "Value":"3" } ] } 

非格式化的JSON

确实反序列化。

 {"Mode":"And","Elements":[{"Name":"ID","Operator":"Equal","Value":"3"}]} 

更新

我提出了一个展示这个问题的示例解决方案 。

你的大部分格式都很好。 你不能在{"__type"之间有任何空格。

请参阅此前一个答案: 使用DataContractJsonSerializer对JSON进行抽象以抽象列表

例如,您的示例代码正在尝试反序列化此JSON字符串:

 "{\r\n\t\"Mode\":\"And\",\r\n\t\"Elements\":\r\n\t[\r\n\t\t{\r\n\t\t\t\"__type\":\"SearchParameter:#JsonTest.Search\",\r\n\t\t\t\"Name\":\"LastName\",\r\n\t\t\t\"Operator\":\"Equal\",\r\n\t\t\t\"Value\":\"Smith\"\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"__type\":\"SearchGroup:#JsonTest.Search\",\r\n\t\t\t\"Mode\":\"Or\",\r\n\t\t\t\"Elements\":\r\n\t\t\t[\r\n\t\t\t\t{\r\n\t\t\t\t\t\"__type\":\"SearchParameter:#JsonTest.Search\",\r\n\t\t\t\t\t\"Name\":\"FirstName\",\r\n\t\t\t\t\t\"Operator\":\"Equal\",\r\n\t\t\t\t\t\"Value\":\"Tim\"\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\t\"__type\":\"SearchParameter:#JsonTest.Search\",\r\n\t\t\t\t\t\"Name\":\"FirstName\",\r\n\t\t\t\t\t\"Operator\":\"Equal\",\r\n\t\t\t\t\t\"Value\":\"Tom\"\r\n\t\t\t\t}\r\n\t\t\t]\r\n\t\t}\r\n\t]\r\n}" 

格式:

 { "Mode":"And", "Elements": [ { "__type":"SearchParameter:#JsonTest.Search", "Name":"LastName", "Operator":"Equal", "Value":"Smith" }, { "__type":"SearchGroup:#JsonTest.Search", "Mode":"Or", "Elements": [ { "__type":"SearchParameter:#JsonTest.Search", "Name":"FirstName", "Operator":"Equal", "Value":"Tim" }, { "__type":"SearchParameter:#JsonTest.Search", "Name":"FirstName", "Operator":"Equal", "Value":"Tom" } ] } ] } 

将其更改为此,错误消失:

 "{\r\n\t\"Mode\":\"And\",\r\n\t\"Elements\":\r\n\t[\r\n\t\t{\"__type\":\"SearchParameter:#JsonTest.Search\",\r\n\t\t\t\"Name\":\"LastName\",\r\n\t\t\t\"Operator\":\"Equal\",\r\n\t\t\t\"Value\":\"Smith\"\r\n\t\t},\r\n\t\t{\"__type\":\"SearchGroup:#JsonTest.Search\",\r\n\t\t\t\"Mode\":\"Or\",\r\n\t\t\t\"Elements\":\r\n\t\t\t[\r\n\t\t\t\t{\"__type\":\"SearchParameter:#JsonTest.Search\",\r\n\t\t\t\t\t\"Name\":\"FirstName\",\r\n\t\t\t\t\t\"Operator\":\"Equal\",\r\n\t\t\t\t\t\"Value\":\"Tim\"\r\n\t\t\t\t},\r\n\t\t\t\t{\"__type\":\"SearchParameter:#JsonTest.Search\",\r\n\t\t\t\t\t\"Name\":\"FirstName\",\r\n\t\t\t\t\t\"Operator\":\"Equal\",\r\n\t\t\t\t\t\"Value\":\"Tom\"\r\n\t\t\t\t}\r\n\t\t\t]\r\n\t\t}\r\n\t]\r\n}" 

格式:

 { "Mode":"And", "Elements": [ {"__type":"SearchParameter:#JsonTest.Search", "Name":"LastName", "Operator":"Equal", "Value":"Smith" }, {"__type":"SearchGroup:#JsonTest.Search", "Mode":"Or", "Elements": [ {"__type":"SearchParameter:#JsonTest.Search", "Name":"FirstName", "Operator":"Equal", "Value":"Tim" }, {"__type":"SearchParameter:#JsonTest.Search", "Name":"FirstName", "Operator":"Equal", "Value":"Tom" } ] } ] } 

奇怪的。 您可能想尝试JSON.NET,一个用于JSON序列化和反序列化的好库。 我最近在一个项目中使用它,它适用于DataContractJsonSerializer失败的情况。

你可以在http://json.codeplex.com/找到它。

这很奇怪,因为以下对我很有用:

 using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Json; using System.Text; public class SomeModel { public string Mode { get; set; } public IEnumerable Elements { get; set; } } public class Element { public string Name { get; set; } public string Operator { get; set; } public string Value { get; set; } } class Program { static void Main() { var json = @"{ ""Mode"":""And"", ""Elements"": [ { ""Name"":""ID"", ""Operator"":""Equal"", ""Value"":""3"" } ] }"; var serializer = new DataContractJsonSerializer(typeof(SomeModel)); using (var stream = new MemoryStream(Encoding.Default.GetBytes(json))) { var model = (SomeModel)serializer.ReadObject(stream); Console.WriteLine(model.Mode); foreach (var element in model.Elements) { Console.WriteLine(element.Name); Console.WriteLine(element.Operator); Console.WriteLine(element.Value); } } } }