-1

I have read a JSON document into a hashtable and started for each loop through the Dinnersets inside of it.

I have stored the current DinnerSet in my Helper class and now I just need to use a string named CurrentMeal which simply contains a mealname and use it something like this:

String MealID = MyHelper.DinnerSet.Value.Meals.CurrentMeal.MealID

My problem is I don't know how to substitute the String CurrentMeal into this and have the whole thing expanded to return me the mealID, If I do this manually:

String MealID = MyHelper.DinnerSet.Value.Meals.Pasta.MealID

I get back the correct MealID, I am sure it is very simple I just don't know what I should be googling to get onto the right track with this

Any help greatly appreciated

EDIT: JSON Structure example:

    "DinnerSet001": 
      "Version": "0.1",
      "Enabled" : true,
      "Description": "These are delicious meals for one",
      "Notes": "May contain Gluten or Nuts",
      "Meals": {
        "Pasta": {
            "MealID": "MID001",
            "Description": "Basic Pasta dish in a tomato and basil sauce",
            "Type": "Vegetarian"
        },

The way I am reading this JSON into an object is:

dynamic DinnerSetsHash = JsonConvert.DeserializeObject<Dictionary<String, dynamic>>(jsonContent);

I then start reading the Dinnersets inside the JSON using:

          foreach (var DinnerSet in DinnerSetsHash) { 

I get CurrentMeal from elsewhere but i know it contains the mealnames i need such as "Pasta" and i am then hoping i should then be able to substitute it and get the MealID i need

    String MealID = MyHelper.DinnerSet.Value.Meals.CurrentMeal.MealID

Regards
K.

Kenneth
  • 13
  • 3
  • Can you show a sample of your JSON structure/layout? – gravity Aug 09 '18 at 19:07
  • sure will do give me 5 mins. Thank you – Kenneth Aug 09 '18 at 19:10
  • OK, that JSON sample helps. Anywhere in your JSON itself (not in your code) do you have a `CurrentMeal` field though? Your sample doesn't show anything like that. Also, do you have a class specifically setup to import the JSON data? That may help as well. Essentially - I can't figure out why you would use `CurrentMeal` at all. – gravity Aug 09 '18 at 19:44
  • ok let me see if i can add more of the code around this to give more context.... thank you all – Kenneth Aug 09 '18 at 19:47
  • 1) Why are you using `dynamic` rather than deserializing to an explicit data model? 2) If you cannot use an explicit data model, why not use `JToken` for which the available methods and properties are explicit and discoverable via IntelliSense? – dbc Aug 09 '18 at 20:57
  • Apologies dbc i just saw your reply, I will look at JToken as a way to achieve this also, I have lots to play with now, thank you also! :) – Kenneth Aug 10 '18 at 06:36

2 Answers2

1

Based on the information you've given, I think what you're looking for is the square bracket syntax, also called "indexer syntax". For example:

string CurrentMeal = "Pasta";
  ...
string MealID = DinnerSet.Value.Meals[CurrentMeal].MealID;

Fiddle: https://dotnetfiddle.net/bEqNFN


I agree with @dbc's comment that you would probably be better off using a strongly typed model rather than dynamic so that you get the benefits of Intellisense and compile-time type checking.

The following model should work based on the JSON you've given:

public class DinnerSet
{
    public string Version { get; set; }
    public bool Enabled { get; set; }
    public string Description { get; set; }
    public string Notes { get; set; }
    public Dictionary<string, Meal> Meals { get; set; }
}

public class Meal
{
    public string MealID { get; set; }
    public string Description { get; set; }
    public string Type { get; set; }
}

You can then deserialize into a Dictionary<string, DinnerSet> (instead of Dictionary<string, dynamic>) and your code should still work with only minimal changes.

Fiddle: https://dotnetfiddle.net/D0T98K

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
0

thank you for the input,

I was thinking this over last night and i think the question i needed to ask all along was how do i deal with a JSON file that is dynamic (as mine is), it could have any number of Dinnersets and they can contain any number of meals.

I did originally go down the strongly typed route using the paste special -> paste JSON as classes in visual studio but that didn't work for me for reasons i forget now.

I will do some testing with "indexer Syntax" thank you for the name of it! it has been driving me crazy :)

I also thought of a another way to represent what i am trying to do, I know for example in PowerShell I could have done this:

     MealID = (DinnerSet.Value.Meals$(CurrentMeal)`.MealID)

and that would expand the entire right hand side and give me the value i am looking for. If there is an equivalent in C# that would also solve this for me.

EDIT: yes the indexer syntax works as the $() does in PowerShell, thanks :)

Other than that i will test with the indexer syntax and Mark your reply as the answer for now, this gives me plenty to play around with, thank you all!

Kenneth
  • 13
  • 3
  • You probably gave up on the strongly typed models because the generator doesn't know when the keys will be dynamic and so will hardcode class names in that case. So what you do is start with the generated classes, then wherever the keys will be dynamic you use a `Dictionary` instead, where `T` is the type of the item data. The model I suggested above uses this approach to handle the dynamic keys for the Meals. Similarly, deserializing into a dictionary at the root handles the dynamic keys for the DinnerSets. The rest of the JSON is not dynamic, so regular classes work fine. – Brian Rogers Aug 10 '18 at 14:52
  • Here is a simpler example of the same thing: [How can I deserialize a child object with dynamic (numeric) key names?](https://stackoverflow.com/q/24771804/10263) – Brian Rogers Aug 10 '18 at 14:55
  • Thanks Brian i think i will look at making this a strongly typed class with the dynamic bits handled as you suggest, it seems like this way it will be a lot simpler in the long run :) – Kenneth Aug 11 '18 at 19:22