0

Note: I'm following this guide: https://weblog.west-wind.com/posts/2012/aug/30/using-jsonnet-for-dynamic-json-parsing

My goal is to have a basic json structure which can adjust to dynamic structures inside it. For example, I have the following structures I am using to store trigger Json data:

public class TriggerJson
{        
    public string TriggerType { get; set; }        
    public string ConfiguredBy { get; set; }
    public dynamic Trigger { get; set; }
}

The above structure will store any dynamic structure in Trigger property. For example, the one below:

public class ExpiryTriggerJson
{
    public string ActionType { get; set; }
    public TriggerRecipient[] Recipients { get; set; }
}
//... more Trigger structures like ExpiryTriggerJson above

I am able to store this fine in an array of TriggerJson. The issue is when I want to update the the structure. For example, I want to update or replace the Trigger property for one of the TriggerJson entries in the array. Below is my code that is having issues casting to Json type when assigning a new ExpiryTriggerJson object to TriggerJson.Trigger property. I am just casting the original TriggerJson array into JArray and going through each entry and when I find an appropriate entry to replace, I try to do so:

        var expiryTriggerJson = new ExpiryTriggerJson
        {
            Recipients = taskRecipients.ToArray(),
            ActionType = TriggerJsonHelper.ExpiryTriggerActionType_Task
        };


            JArray tjList = JArray.Parse(originalTriggersJson);
            foreach (dynamic triggerJson in tjList)
            {
                if (triggerJson.TriggerType == ExpiryTriggerType)
                {
                    triggerJson.Trigger = expiryTriggerJson; // this line is throwing an exception
                    triggerJson.ConfiguredBy = configuredBy;
                }
            }
            return JsonConvert.SerializeObject(tjList);

My question is: is it possible to modify an existing json structure in this manner? Or should I have a different approach?

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Riz
  • 6,486
  • 19
  • 66
  • 106
  • 1
    Every time you use `dynamic`, always think to yourself there is a better faster and safer way. Always know you will end up in a situation like this sooner or later. – TheGeneral Feb 05 '21 at 01:14
  • _"// this line is throwing an exception"_ - what exception? And why do you expect that `JArray.Parse` will result in a list of `TriggerJson` (it won't)? – ProgrammingLlama Feb 05 '21 at 01:14
  • because I'm creating a list of TriggerJson and serializing it originally. This function is just showing when I want to update that list. The foreach loop works and gets into each entry. – Riz Feb 05 '21 at 01:22
  • _"because I'm creating a list of TriggerJson and serializing it originally."_ - That doesn't mean it will return it to a collection of `TriggerJson` - it has no way to know that you want to do that. You probably want `List tjList = JsonConvert.DeserializeObject>();` – ProgrammingLlama Feb 05 '21 at 01:31
  • ah ok thanks. I understand. I thought for some reason parsing was enough. Now it works fine. If you provide it as an answer, I can mark it as such. – Riz Feb 05 '21 at 01:43

1 Answers1

0

Your problem is probably with these lines (mainly the Parse line):

JArray tjList = JArray.Parse(originalTriggersJson);
foreach (dynamic triggerJson in tjList)

JArray has no way of knowing what type of object the JSON you're parsing represents, so it will parse it as an array of JObject (in this case), not an array of TriggerJson.

What you actually want to do is parse it as a list of TriggerJson:

List<TriggerJson> tjList = JsonConvert.DeserializeObject<List<TriggerJson>>(originalTriggersJson);

And then you might as well do with the dynamic type in the loop since we know the type:

foreach(TriggerJson triggerJson in tjList)

And this should solve your problem.

P.S. Instead of using dynamic for the Trigger property, you might want to look into a common base class and a JsonConverter as, again, JSON.NET doesn't know what type you're deserializing to, so the Trigger property will be deserialized to a JObject rather than a specific type.

This might give you an idea how to approach that, though it's probably easier if you include a string property to indicate the type of trigger you've got, and then read that property when you deserialize it with the converter.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86