C# JSON как прочитать значение c с неизвестным именем родителя - PullRequest
3 голосов
/ 08 апреля 2020

Я хочу прочитать дату "datum" из этой строки json в список DateTime:

{
  "Neujahrstag": {
    "datum": "2016-01-01",
    "hinweis": ""
  },
  "Karfreitag": {
    "datum": "2016-03-25",
    "hinweis": ""
  },
  "Ostermontag": {
    "datum": "2016-03-28",
    "hinweis": ""
  },
  "Tag der Arbeit": {
    "datum": "2016-05-01",
    "hinweis": ""
  },
  "Christi Himmelfahrt": {
    "datum": "2016-05-05",
    "hinweis": ""
  },
  "Pfingstmontag": {
    "datum": "2016-05-16",
    "hinweis": ""
  },
  "Tag der Deutschen Einheit": {
    "datum": "2016-10-03",
    "hinweis": ""
  },
  "Reformationstag": {
    "datum": "2016-10-31",
    "hinweis": ""
  },
  "1. Weihnachtstag": {
    "datum": "2016-12-25",
    "hinweis": ""
  },
  "2. Weihnachtstag": {
    "datum": "2016-12-26",
    "hinweis": ""
  }
}

Я понятия не имею, как это сделать.

Я использую следующий код, чтобы получить строку json и проанализировать ее, но я не знаю, как получить список или массив.

using (WebClient wc = new WebClient())
            {
                var json = wc.DownloadString("https://feiertage-api.de/api/?jahr=2020&nur_land=MV");

                JObject result = JObject.Parse(json);

                MessageBox.Show(DateTime.ParseExact(result.First.First.First.First.ToString(), "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString());
            }

Существует ли простой способ сделать это или я должен написать костюмный десериализатор для такого рода json?

Ответы [ 4 ]

3 голосов
/ 08 апреля 2020

Я рекомендую решение @ RoadRunner, так как оно чистое и правильное. Тем не менее я оставлю здесь быстрый и грязный путь для справки

// ...
JObject result = JObject.Parse(json);

foreach (var child in result.Children())
{
    var holidayName = child.Path;
    var dateString = child.First["datum"].Value<string>();
    var date = DateTime.ParseExact(dateString, "yyyy-MM-dd", CultureInfo.InvariantCulture);
}
// ...
3 голосов
/ 08 апреля 2020

Самый простой способ - создать класс для ваших внутренних объектов:

public class Data
{
    public DateTime Datum { get; set; }
    public string HinWeis { get; set; }
}

Затем используйте Json. NET для десериализации вашего JSON в Dictionary<string, Data> и извлекать каждый Datum из значений:

using (WebClient wc = new WebClient())
{
    var json = wc.DownloadString("https://feiertage-api.de/api/?jahr=2020&nur_land=MV");

    var result = JsonConvert.DeserializeObject<Dictionary<string, Data>>(json);

    foreach (var kvp in result)
    {
        Console.WriteLine(kvp.Value.Datum.ToString("yyyy-MM-dd"));
    }
}

Вывод:

2020-01-01
2020-04-10
2020-04-13
2020-05-01
2020-05-21
2020-06-01
2020-10-03
2020-10-31
2020-12-25
2020-12-26
0 голосов
/ 08 апреля 2020

Еще одно решение

foreach (var item in JObject.Parse(json).Values())
{
    DateTime date = item.Value<DateTime>("datum");
    Console.WriteLine(date.ToString("yyyy-MM-dd"));
}
0 голосов
/ 08 апреля 2020

Я нахожу способ решить мою проблему для использования другими.

            var publicHolidays = new List<DateTime>();

            using (WebClient wc = new WebClient())
            {
                var json = wc.DownloadString("https://feiertage-api.de/api/?jahr=2020&nur_land=MV");

                var result = (JObject)JsonConvert.DeserializeObject(json);

                IEnumerable<JToken> dates = result.SelectTokens("$..datum");

                foreach (String s in dates)
                {
                    publicHolidays.Add(DateTime.ParseExact(s.ToString().Substring(0, 10), "yyyy-MM-dd", CultureInfo.InvariantCulture));
                }

            }

Не уверен, что это умное решение, но оно работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...