DataContractJsonSerializer не работает с отформатированным JSON?

при использовании 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)

форматированный JSON

этой не десериализовать, выбрасывая исключение выше.

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

не отформатированный JSON

этой тут десериализовать.

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

обновление

Я поставил образец решения что показывает эту проблему.

3 ответов


большая часть вашего форматирования на самом деле в порядке. У вас просто не может быть пробелов между { и "__type".

посмотреть этот предыдущий ответ: десерализация JSON в абстрактный список с помощью 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"
                }
            ]
        }
    ]
}

странно. Вы можете попробовать 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<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);
            }
        }
    }
}