Orko
Orko

Reputation: 47

C# JSON how to read a specific value with unknown Parentname

i want to read the Date "datum" form this json string in to a List of 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": ""
  }
}

I have no idea how to do that.

I use the following code to get the json string and parse it but i have no idea how to get to a List or Array.

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());
            }

Is there an easy way to do this or do i have to write a costume deserializer for this kind of json?

Upvotes: 3

Views: 117

Answers (4)

Roman Marusyk
Roman Marusyk

Reputation: 24589

One more solution

foreach (var item in JObject.Parse(json).Values())
{
    DateTime date = item.Value<DateTime>("datum");
    Console.WriteLine(date.ToString("yyyy-MM-dd"));
}

Upvotes: 0

Orko
Orko

Reputation: 47

I find a way to solve my problem for others to use.

            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));
                }

            }

Not sure if this is a smart solution but it works for me.

Upvotes: 0

Markus Deibel
Markus Deibel

Reputation: 1329

I recommend @RoadRunner's solution since it's the clean and correct way. Still I'll leave the quick n dirty way here for reference

// ...
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);
}
// ...

Upvotes: 3

RoadRunner
RoadRunner

Reputation: 26315

An easy way would be to create a class for your inner objects:

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

Then use Json.NET to deserialize your JSON into a Dictionary<string, Data> and fetch each Datum from the values:

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"));
    }
}

Output:

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

Upvotes: 3

Related Questions