Десериализовать многотипный массив JSON с помощью DataContracts

В настоящее время у меня есть некоторые данные JSON, которые я пытаюсь десериализовать с помощью класса DataContractJsonSerializer. Однако один из массивов данных содержит несколько типов объектов. Есть ли способ правильно десериализовать эти данные? Я знаю, что существует очень похожий вопрос, но я бы предпочел не использовать Json.NET или любой другой сторонний партийные библиотеки.

EDIT: Небольшой пример:

В этом случае допустим, что JSON имеет форму [{"foo":string},{"bar":string},{"foo":string},{"foo":string},...], где каждый элемент имеет форму {"foo":string} или {"bar":string}. Затем контракты могут быть настроены следующим образом:

[DataContract]
class Foo { [DataMember] public string foo; }

[DataContract]
class Bar { [DataMember] public string bar; }

В этом контексте мой вопрос: как мне десериализовать этот массив Foos и Bars?


person LegionMammal978    schedule 22.02.2017    source источник
comment
However, one of the arrays in the data contains multiple types of objects -- не могли бы вы привести пример? Чем отличаются эти типы объектов? Если по какой-то причине они совершенно разные, вы можете рассмотреть тип dynamic. Было бы полезно опубликовать образец JSON и модель, в которую вы пытаетесь его десериализовать.   -  person Shane Ray    schedule 22.02.2017
comment
@ShaneRay Добавил небольшой пример, в реальном случае мои Foo и Bar имеют совершенно разные свойства.   -  person LegionMammal978    schedule 22.02.2017


Ответы (1)


Это звучит неправильно. В одном массиве не должно быть двух совершенно разных типов. Учитывая предоставленный JSON, я бы попробовал что-то вроде этого....

[DataContract]
class SomeClass
{
    [DataMember]
    public string foo { get; set;}
    [DataMember]
    public string bar { get; set;}
}

Затем проверьте наличие IsNullOrWhiteSpace() в каждом свойстве.

Обновлено с дополнительным кодом...

   static void Main(string[] args)
    {
        SomeClass[] output;
        var json = "[{\"foo\":\"value\"},{\"bar\":\"value\"},{\"foo\":\"value1\"},{\"foo\":\"value1\"}]";

        using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
        {
            var deserializer = new DataContractJsonSerializer(typeof(SomeClass[]));
             output = (SomeClass[])deserializer.ReadObject(ms);
        }

        // do something with output
        Console.WriteLine(output.Length);
    }
person Shane Ray    schedule 22.02.2017
comment
В частности, я запрашиваю определенный веб-API JSON, который дает 2 ответа (с разными форматами) в массиве. - person LegionMammal978; 22.02.2017
comment
В этом случае вам нужно иметь две отдельные модели. Для первого вызова API, который возвращает массив, вы десериализуете его в ModelA. Второй вызов API вы десериализуете в ModelB. - person Shane Ray; 22.02.2017
comment
Я думаю, вы неправильно понимаете, что я пытаюсь сказать. Я передаю один запрос на сервер и получаю один ответ с массивом с Foo и Bar. Я спрашиваю здесь, как десериализовать этот массив, чтобы получить в нем Foo и Bar. - person LegionMammal978; 22.02.2017
comment
Предоставленный вами JSON представляет собой массив объектов... Похоже, вы имеете в виду словарь, но foo повторяется, поэтому он не может быть индексатором. Я обновил свой ответ дополнительным примером кода. - person Shane Ray; 22.02.2017
comment
Таким образом, единственное решение - создать объединение двух и установить для него тип массива? - person LegionMammal978; 22.02.2017
comment
Это лучшее решение, которое я могу придумать, учитывая предоставленные данные. Если бы у меня был пример конечной точки или лучший пример возвращаемого JSON, могут быть другие варианты. - person Shane Ray; 22.02.2017
comment
Если этот ответ помог решить вашу проблему, отметьте его как ответ. - person Shane Ray; 22.02.2017
comment
Я так и сделаю, просто подожду день или два, чтобы убедиться, что не появятся лучшие ответы. - person LegionMammal978; 22.02.2017