Десериализация JSON с использованием JSon.NET с динамическими данными - PullRequest
17 голосов
/ 05 января 2012

Я пытаюсь десериализовать некоторые данные JSON в объекты для приложения.До сих пор это было нормально, потому что свойства данных JSON были статическими (ключ со значением).Теперь у меня есть результат, где ключ представляет собой динамический фрагмент данных.

Вот пример URL JSON:

http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info

В результате получается JSON для этого:

{ "query" : { "pages" : { "6695" : { "counter" : "",
          "lastrevid" : 468683764,
          "length" : 8899,
          "ns" : 0,
          "pageid" : 6695,
          "title" : "Citadel",
          "touched" : "2012-01-03T19:16:16Z"
        } } } }

Хорошо, это здорово, но я не могу десериализовать данные "страниц" в объект.Если бы я определил класс для страниц, он бы выглядел следующим образом:

public class 6695
{
    public string counter { get; set; }
    public int lastrevid { get; set; }
    public int length { get; set; }
    public int ns { get; set; }
    public int pageid { get; set; }
    public string title { get; set; }
    public string touched { get; set; }
}

Для того, чтобы десериализовать содержимое (используя JsonConvert.Deserialize (jsondata)), и мы все знаем, что не можеместь класс с именем 6695. Мало того, что имя класса должно быть другим (например, pageid = 7145 должно быть классом 7145).

Может показаться, что я могу вытащить некоторые значения, еслиЯ использую что-то вроде JObject.Parse (content), а затем обращаюсь к элементам как JArrays, но это довольно уродливо, и я все еще пытаюсь получить данные из массива страниц.

Ищу кого-то, кто поможет сэтот.Я не думаю, что это необычно, это просто не JSON-данные, с которыми я сталкивался раньше и не уверен, как с этим справиться.

Спасибо!

PS забыл упомянуть, что это на Windows Phone7, поэтому «динамический» недоступен!

Ответы [ 6 ]

27 голосов
/ 05 января 2012

Самый простой способ. В этом конкретном случае, вероятно, будет идти dynamic.

dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
var lastRevId = data.query.pages["6695"].lastrevid;

Вы можете ссылаться на любой элемент по имени [], чтобы вы могли сделать что-то вроде data["query"]["pages"]["6695"]["lastrevid"]. Это достанется всем тем маленьким объектам, имя которых недопустимо в c #.

18 голосов
/ 05 января 2012

Вот как вы используете https://github.com/facebook-csharp-sdk/simple-json (https://nuget.org/packages/SimpleJson).

var text = "{\"query\":{\"pages\":{\"6695\":{\"pageid\":6695,\"ns\":0,\"title\":\"Citadel\",\"touched\":\"2012-01-03T19:16:16Z\",\"lastrevid\":468683764,\"counter\":\"\",\"length\":8899}}}}";

(Использование динамического)

dynamic json = SimpleJson.DeserializeObject(text);
string title = json.query.pages["6695"].title;

foreach (KeyValuePair<string, dynamic> page in json.query.pages)
{
    var id = page.Key;
    var pageId = page.Value.pageid;
    var ns = page.Value.ns;
}

(Использование строго типизированногоклассы)

class result
{
    public query query { get; set; }
}
class query
{
    public IDictionary<string, page> pages { get; set; }
}
class page
{
    public long pageid { get; set; }
    public string title { get; set; }
}

var result = SimpleJson.DeserializeObject<result>(text);

[Обновить]

на Windows Phone, где динамическая не поддерживается и вы не хотите использовать строго типизированные классы.

var json = (IDictionary<string, object>)SimpleJson.DeserializeObject(text);
var query = (IDictionary<string, object>)json["query"];
var pages = (IDictionary<string, object>)query["pages"];
var pageKeys = pages.Keys;
var page = (IDictionary<string, object>)pages["6695"];
var title = (string)page["title"];
2 голосов
/ 14 января 2016

Я надеюсь, что приведенный ниже пример поможет.Я всегда проектирую модель, которая соответствует JSON.Намного лучше работать с объектом, когда это ваш собственный дизайн модели.

Очень легко создать модель c # из json.Я использую этот сайт для создания модели: http://json2csharp.com

Полный пример:

C # Код:

    var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourModel>(jsonString);

JSON:

    {
      "investors": [
        {
          "name": "06",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "07",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": "7.0"
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "08",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": "7.0"
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "09",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "10",
          "programs": [
            {
              "name": "Conventional",
              "value": ""
            },
            {
              "name": "FHA - Standard",
              "value": ""
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": ""
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": "2.0"
            }
          ]
        },
        {
          "name": "11",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "6.0"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "12",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "13",
          "programs": [
            {
              "name": "Conventional",
              "value": ""
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": ""
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": "2.0"
            }
          ]
        }
      ]
    }

Модель:

    public class Program
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class Investor
    {
        public string name { get; set; }
        public List<Program> programs { get; set; }
    }

    public class RootObject
    {
        public List<Investor> investors { get; set; }
    }
1 голос
/ 09 мая 2014

Используя Json.net, вы можете просто:

Dictionary<string,object> result = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
foreach(var item in result)
    Console.WriteLine(item.Key + " " + item.Value);
0 голосов
/ 04 августа 2013

Возможно, вы могли бы просто использовать один зарезервированный атрибут для хранения типа объекта, а затем использовать базовый тип, как показано в этой статье: Динамические типы с JSON.NET

0 голосов
/ 05 января 2012

Как насчет простого поиска и замены в строке JSON? Хотя это может быть не самое элегантное решение, оно, возможно, будет самым прагматичным.

...