1
DataTable LoadJsonFile(string Algorithm_)
{
    OpenFileDialog openFileDialog = new OpenFileDialog();
    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
        List<SaveEcoBot_Object> saveEcoBot_Objects = new List<SaveEcoBot_Object>();
        string jsonStr = File.ReadAllText(openFileDialog.FileName);
        StreamReader file = File.OpenText(openFileDialog.FileName);
        JsonTextReader jsonTextReader = new JsonTextReader(file);
        var token = JToken.Parse(jsonStr);
        if(token is JArray)
        {
            JArray jsonArray = JToken.ReadFrom(jsonTextReader) as JArray;
            foreach (JObject obj in jsonArray)
            {
                SaveEcoBot_Object saveEcoBot_Object = new SaveEcoBot_Object();
                saveEcoBot_Object.id = obj["id"].Value<string>();
                saveEcoBot_Object.cityName = obj["cityName"].Value<string>();
                saveEcoBot_Object.stationName = obj["stationName"].Value<string>();
                saveEcoBot_Object.localName = obj["localName"].Value<string>();
                saveEcoBot_Object.timezone = obj["timezone"].Value<string>();
                saveEcoBot_Object.latitude = obj["latitude"].Value<float>();
                saveEcoBot_Object.longitude = obj["longitude"].Value<float>();
                foreach (JObject pollutantobj in obj["pollutants"])
                {
                    SaveEcoBotObject_Pollutant saveEcoBotObject_Pollutant = new SaveEcoBotObject_Pollutant();
                    saveEcoBotObject_Pollutant.pol = pollutantobj["pol"].Value<string>();
                    saveEcoBotObject_Pollutant.unit = pollutantobj["unit"].Value<string>();
                    saveEcoBotObject_Pollutant.time = pollutantobj["time"].Value<string>();
                    saveEcoBotObject_Pollutant.value = pollutantobj["value"].Value<string>();
                    saveEcoBotObject_Pollutant.averaging = pollutantobj["averaging"].Value<string>();
                    saveEcoBot_Object.pollutants.Add(saveEcoBotObject_Pollutant);
                }
                saveEcoBot_Objects.Add(saveEcoBot_Object);
            }
        }
        return null;
    }
    else
    {
        return null;
    }
}

  • 2
    Если строка уникальная, то как вы определите, что это за "строка"? Вам ведь надо как то обратиться к свойствам этого объекта, верно? Ну и к чему будете обращаться? Что вообще такое "Уникальная строка"? – EvgeniyZ May 25 '21 at 17:50
  • 6
    JsonSerializer.Deserialize<T>(jsonString)? – VladD May 25 '21 at 17:51
  • Переводите а jsonobject зачем вам конкретный если оно все равно не известно – Aziz Umarov May 25 '21 at 18:50
  • 3
    dynamic jsonResponse = JsonConvert.Deserialize(json); – iikuzmychov May 25 '21 at 19:20
  • Я переформулирую свой вопрос выше (ибо не пойму, почему все залайкали коммент, где явно нужно указывать тип). Вот допустим, я вам даю такой JSON { "Message" : "Привет SO!" } или [{ "Age" : 23 }, { "Age" : 50 }] они вам подходят? Тут есть нужная для вас информация? Если есть, то вы явно хотите сделать некий "визуализатор" для JSON, который отобразит все, что угодно. Тогда встает другой вопрос: а зачем вам "десиализация в объект"? Если не подходит, то значит у вас нету "уникальности", ибо есть некое связующее звено, о котором вы нам не говорите. И тут уже зависит от того, что это за "звено". – EvgeniyZ May 25 '21 at 20:09
  • @EvgeniyZ: Я понял текст вопрос «в объект класса» как «в объект заранее известного класса». Если класс заранее неизвестен, то и смысла нет, т. к. с полученным объектом будет невозможно работать – VladD May 25 '21 at 21:04
  • Судя по вопросу и последующему описанию в комменте, нужно какой-то супер универсальный десериализатор. Для этого сначала нужно сделать адекватный парсер, то есть разбить входящий json по компонентам, которые в него входят, можно использовать всё что угодно на выбор : регулярки, обычный сплит строки по заранее продуманной логике, изврат с обратной польской записью. А уж после парсинга делать десериализацию. Ваша задача нетривиальна, поэтому решение больше творческое, чем техническое. – SoulOFTrue May 25 '21 at 21:15
  • 1
    @VladD не зная структуры строки - это я расцениваю как "нам совершенно неизвестен JSON, неизвестно что там". То есть, не зная структуры строки == Нам неизвестен T. Вот я и хочу узнать у автора, как он дальше хочет взаимодействовать с данными "не зная их". Может там статичное поле, а остальное все динамично, может объект целиком меняется и надо искать нужное свойство, может вовсе что-то другое. – EvgeniyZ May 25 '21 at 21:16
  • Суперуниверсальный десериализатор — это в JObject. – VladD May 25 '21 at 21:34
  • Ну или JsonDocument.Parse в System.text.Json. – VladD May 25 '21 at 21:41
  • Извините, наверное я не корректно сформулировал вопрос. Возможно ли динамически создавать объект класса в зависимости от json объекта? А задача следующая: Есть сайт ( https://api.saveecobot.com/output.json ) и все элементы записать в DataTable и использовать в компоненте DataGridView – Alexandr Kruzer May 25 '21 at 22:57
  • 1
    @AlexandrKruzer Вы нам "динамику" то покажете? По ссылке у вас статичный объект, с четко сформированной структурой. О какой динамически создавать объект идет речь? Что у вас не получается? – EvgeniyZ May 25 '21 at 23:33
  • Не получается отображать в DataGridView ( используя DataTable ) JSON объекты. К примеру те что по ссылке. Я написал функцию, которая частично выполняет эту задачу, но теряет вложенные массивые. Код функции ниже: – Alexandr Kruzer May 25 '21 at 23:58
  • 1
    @AlexandrKruzer Это должно быть в вопросе (кнопка "править" под ним), а не опубликован как "ответ", удалите. По поводу вашего кода, почему вы делаете "ручную" десериализацию? Почитайте это и это. – EvgeniyZ May 26 '21 at 00:30
  • @EvgeniyZ я хотел бы обойтись без создания класса для заранее известной структры JSON. Просто хочу сделать средство визуализации через DataGridView используя DataTable. – Alexandr Kruzer May 26 '21 at 19:02
  • @AlexandrKruzer Забудьте про DataGridView, это UI, для него надо сначала подготовить данные. А подготовленные данные, это класс. Почему вы вдруг решили от класса отказаться? Не нужны все свойства? Вас не заставляют их все писать, напишите только нужные вам. Не, ну можете работать с JObject или аналогом, тогда будете писать вручную var result = data["НекоеСвойство"]["СвойствоВнутриПредыдущего"];, но сразу учтите, что если изменится вдруг JSON строка на сервере, вам везде текст НекоеСвойство надо будет менять, а так, вам надо лишь подправить класс будет. – EvgeniyZ May 26 '21 at 19:09
  • @EvgeniyZ данные подготовил. Новая функция сверху. Как я могу интерпретировать их в DataTable? Основная проблема заключается в том, что я не представляю как отобразить вложенный в объект массив в ячейке DataGrid-а. – Alexandr Kruzer May 26 '21 at 20:02
  • @AlexandrKruzer Значит не подготовили, раз не можете их нормально вывести. Не так давно был этот вопрос, посмотрите. – EvgeniyZ May 26 '21 at 20:28
  • @EvgeniyZ вывести то я вывел ( прикрепил скриншот ). Но как в одну ячейку записать данные с вложенного в каждый объект массива "pollutants", чтобы оно было красиво? – Alexandr Kruzer May 26 '21 at 20:52
  • Так может стоит задать вопрос именно про это: как отобразить вложенный массив в виде одного значения? – Alexander Petrov May 27 '21 at 23:11

1 Answers1

0

Достаточно простейшего кода:

string json = File.ReadAllText("data.json");
object data = JsonConvert.DeserializeObject(json);
dataGridView.DataSource = data;

При этом в датагриде будут отображаться все данные. В колонке "pollutants" будет json-массив в виде строки текста.
Это не очень читабельно, поэтому могу предложить следующее.

Используем стандартный способ Master/Detail.
На форме должно быть два датагрида.

string json = File.ReadAllText("data.json");
var jArray = JArray.Parse(json);

bindingSource = new BindingSource(); bindingSource.CurrentChanged += BindingSource_CurrentChanged; bindingSource.DataSource = jArray;

masterDataGridView.DataSource = bindingSource; masterDataGridView.Columns["pollutants"].Visible = false;

private void BindingSource_CurrentChanged(object sender, EventArgs e)
{
    var jObject = (JObject)bindingSource.Current;
    detailDataGridView.DataSource = jObject["pollutants"];
}

Данные парсим в JArray. Его привязываем к BindingSource. И далее привязываем к первому гриду.

В событии изменяем источник данных второго грида.