Страницы

Поиск по вопросам

четверг, 9 апреля 2020 г.

Json Serialization, как правильно достать данные из гетерогенного массива?

#c_sharp #json #vkontakte_api

                    
Хочу вытянуть ID групп ВК, у которых в названии есть буква "а".
Отправляю запрос и получаю ответ:

{  
    "response":[  
        747369,
        {  
            "gid":60386075,
            "name":"Мың бір оқиға [K-POP]",
            "screen_name":"kazanonim",
            "is_closed":0,
            "type":"page",
            "is_admin":0,
            "is_member":0,
            "photo":"http:\/\/cs631116.vk.me\/v631116892\/bfa5\/mv5UyEdPfz8.jpg",
            "photo_medium":"http:\/\/cs631116.vk.me\/v631116892\/bfa4\/EEzzOElvS78.jpg",
            "photo_big":"http:\/\/cs631116.vk.me\/v631116892\/bfa2\/ktxcZIgNLVU.jpg"
        },
        ....
    ]
}


Но дальше у меня проблема, не могу достать правильно данные, если я делаю как в коде
ниже, то мне мешает : 747369 - количество групп у которых есть буква "а" в названии.
Я не знаю как обработать его, в результате получаю ошибку 


  newtonsoft.json.jsonserializationexception error converting value 747369 ...


public void Reader2(string r)
{
     Json2.RootObject groups = JsonConvert.DeserializeObject(r);
     foreach (var c in groups.items)
        {
          textBox1.Text += c.screen_name  + Environment.NewLine;
        }
}


public class Json2
{
    public class Item
    {
        public int id { get; set; }
        public string name { get; set; }
        public string screen_name { get; set; }
        public int is_closed { get; set; }
        public string type { get; set; }
        public int is_admin { get; set; }
        public int is_member { get; set; }
        public string photo_50 { get; set; }
        public string photo_100 { get; set; }
        public string photo_200 { get; set; }
    }
     public class RootObject
    {
        public List items { get; set; }
    }
}


Попробовал через http://json2csharp.com/ создать класс:

public class RootObject
{
    public List response { get; set; }
}

Json2.RootObject groups = JsonConvert.DeserializeObject(r);
foreach (var c in groups.response)
{
    textBox1.Text += c + Environment.NewLine;
}


И вот результат:

{
  "gid": 60386075,
  "name": "Мың бір оқиға [K-POP]",
  "screen_name": "kazanonim",
  "is_closed": 0,
  "type": "page",
  "is_admin": 0,
  "is_member": 0,
  "photo": "http://cs631116.vk.me/v631116892/bfa5/mv5UyEdPfz8.jpg",
  "photo_medium": "http://cs631116.vk.me/v631116892/bfa4/EEzzOElvS78.jpg",
  "photo_big": "http://cs631116.vk.me/v631116892/bfa2/ktxcZIgNLVU.jpg"
}


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


Ответы

Ответ 1



Необходимые свойства можно найти с помощью JSONPath // #r "\Newtonsoft.Json\6.0.3\lib\net45\Newtonsoft.Json.dll" using Newtonsoft.Json; using Newtonsoft.Json.Linq; var json = System.IO.File.ReadAllText(@"C:\Temp\json.txt"); var jo = JObject.Parse(json); foreach (var o in jo.SelectTokens("..screen_name")) // JSONPath if (o.ToString().Contains("a")) Console.WriteLine(o.Parent.Parent["gid"] + " " + o); Результат 60386075 kazanonim Для следующего json в файле C:\Temp\json.txt { "response":[ 747369, { "gid":60386075, "name":"Мың бір оқиға [K-POP]", "screen_name":"kazanonim", "is_closed":0, "type":"page", "is_admin":0, "is_member":0, "photo":"http:\/\/cs631116.vk.me\/v631116892\/bfa5\/mv5UyEdPfz8.jpg", "photo_medium":"http:\/\/cs631116.vk.me\/v631116892\/bfa4\/EEzzOElvS78.jpg", "photo_big":"http:\/\/cs631116.vk.me\/v631116892\/bfa2\/ktxcZIgNLVU.jpg" } ] }

Ответ 2



Перед десериализацией можно получить ответ сервера в виде дерева и отредактировать. Примерно так: var jroot = JObject.Parse(r); var jresponse = (JArray)jroot["response"]; jresponce.RemoveAt(0); var root = jroot.ToObject(); Если же это число также нужно, то можно поступить так: public class RootObject { public List response { get; set; } } // ... Json2.RootObject groups = JsonConvert.DeserializeObject(r); foreach (var c in groups.response) { if (c is JObject) { var item = c.ToObject(); // ... } if (c is JValue) { var count = (int)c; // ... } }

Комментариев нет:

Отправить комментарий