使用DataContractJsonSerializer
反序列化JSON时,如果输入中有选项卡(格式化JSON),则序列化程序会抛出异常(如下所示)。如果我用“”替换所有空格,制表符和换行符,序列化程序就可以很好地反序列化它。
这是什么交易?
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)
此不反序列化,抛出上述异常。
{
"Mode":"And",
"Elements":
[
{
"Name":"ID",
"Operator":"Equal",
"Value":"3"
}
]
}
确实反序列化。
{"Mode":"And","Elements":[{"Name":"ID","Operator":"Equal","Value":"3"}]}
我提出了一个显示此问题的sample solution。
答案 0 :(得分:4)
你的大部分格式都很好。您在{
和"__type"
之间不能有任何空格。
请参阅上一个答案:JSON deseralization to abstract list using DataContractJsonSerializer
例如,您的示例代码正在尝试反序列化此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"
}
]
}
]
}
答案 1 :(得分:1)
怪异。您可能想尝试JSON.NET,这是一个很好的JSON序列化和反序列化库。我最近在一个项目中使用它,它适用于DataContractJsonSerializer失败的情况。
找到它答案 2 :(得分:-1)
这很奇怪,因为以下内容对我很有用:
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<Element> 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);
}
}
}
}