Страницы

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

суббота, 15 февраля 2020 г.

Обращение к элементам массива из словарей. Десериализация Json строки

#c_sharp #json #словари


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


  {"response":{"map_width":80,"map_height":80,"map_sp":5541,"objects":[{"type":1,"health":100},{"type":1,"health":100},{"type":1,"health":100},{"type":1,"health":100},{"type":1,"health":100}]}


Я могу спокойно получить все данные, кроме objects.
Объявление массива словарей такое: public System.Collections.Generic.Dictionary[] Field_Params;.
Попытка получения данных из массива Field_Params This_Field.Field_Params[0]["type"]
безуспешна т.к. я не могу обратиться к конкретному словарю.
Помогите, пожалуйста. Либо с тем, как получить данные из конкретного словаря в массиве,
либо как лучше десериализовать возвращаемую сервером строку.
Код скрипта, который получает данные с сервера:  

using System.Net;
using Newtonsoft.Json;
using UnityEngine;
using System.Collections.Generic;

public class Web_Queries : MonoBehaviour
// Класс Веб- запросов
{
    public class Web_Field
    // Поле с данными, получаемыми с сервера
    {
        // Ответ с сервера
        [JsonProperty("response")]
        public Dictionary[] Response;
        // Ответ с сервера
        [JsonProperty("debug")]
        public string Description;
    }

    public Web_Field Get (string Url)
    // Get- запрос
    {
        // Объявляем новый экземпляр класса Web_Field
        Web_Field New_WF = new Web_Field();
        // Проверка подлинности сертефиката сайта
        ServicePointManager.ServerCertificateValidationCallback = delegate { return
true; };
        string Common_Response;
        // Создание нового объекта класса
        using (var Connection = new WebClient())
        {
            // Запрос на сайт
            Common_Response = Connection.DownloadString(Url);
        }
        New_WF = JsonConvert.DeserializeObject(Common_Response);
        // Вернуть ответ с сервера
        return New_WF;
    }
}

    


Ответы

Ответ 1



Вариант 1: Возьмем ваш JSON и прогоним его через этот сайт. В ответ получаем структуру необходимых классов для грамотной десериализации JSON. Я смотрю у вас стоит JSON.NET, поэтому используем его, десериализируем строку в наш объект: var json = JsonConvert.DeserializeObject(file);. Дальше без проблем можно получить доступ ко всему, что нам необходимо, например циклом пройтись по все данным из objects. В итоге получаем что то вроде: public class Object { public int type { get; set; } public int health { get; set; } } public class Response { public int map_width { get; set; } public int map_height { get; set; } public int map_sp { get; set; } public List objects { get; set; } } public class RootObject { public Response response { get; set; } } var file = "{\"response\":{\"map_width\":80,\"map_height\":80,\"map_sp\":5541,\"objects\":[{\"type\":1,\"health\":100},{\"type\":1,\"health\":100},{\"type\":1,\"health\":100},{\"type\":1,\"health\":100},{\"type\":1,\"health\":100}]}}"; var json = JsonConvert.DeserializeObject(file); foreach (var item in json.response.objects) { Console.WriteLine($"Type: {item.type}. Health {item.health}"); } Вариант 2 (без использования классов): Парсим строку в JObject, методом Parse. Получаем небходимые данные, путем добавления некого индекса к нашему JObject. Сам код: var file = "{\"response\":{\"map_width\":80,\"map_height\":80,\"map_sp\":5541,\"objects\":[{\"type\":1,\"health\":100},{\"type\":1,\"health\":100},{\"type\":1,\"health\":100},{\"type\":1,\"health\":100},{\"type\":1,\"health\":100}]}}"; var json = JObject.Parse(file); foreach (var item in json["response"]["objects"]) { Console.WriteLine($"Type: {item["type"]}. Health {item["health"]}"); } Второй вариант хорошо подойдет маленькой утилите, которая использует небольшие данные JSON, на большом проекте его будет трудно изменять/масштабировать под сервер, ибо изменится значение на сервере - придется все строки переписывать и во всем коде. В первом варианте у вас есть структура, классы, которые соответствую тому, что есть на сервере в формате JSON, изменится у сервера что либо - быстро подправили класс и в нужном месте исправили ошибки. Что выбирать - решать вам.

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

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