I'm using Newtonsoft to deserialize an known JSON object and retrieve some values from it if they're present.
The crux is there is that object structure may keep changing so I'm using dynamic to traverse the structure and retrieve the values. Since the object structure keeps changing, I'm using the null conditional operator to traverse the JSON.
The code looks like this
dynamic jsonMeta = JsonConvert.DeserializeObject<dynamic>(jsonScript);
string gVal = jsonMeta.a?.b?.c?.d?.e?.f?.g?.Value ?? ""
The whole idea of this is to traverse the object in a null safe manner so that if a member doesn't exist, it evaluates to null
and it assigns it a default value without throwing an exception. But what I'm seeing is that I get a exception 'Newtonsoft.Json.Linq.JValue' does not contain a definition for 'e'
if that member d is null
.
My understanding is that while the Value of d
is null
, it's of type JValue
so that's why the null conditional operator doesn't work, but then it tries to access member e
inside d
it throws the exception.
So my question is how can I make this work in C#? Is there an easy way to access the JSON members without knowing the JSON structure in a single line or relatively easy way?
Unfortunately due to the design limitation of NewtonSoft JSON.NET it cannot use null coalescing or null conditional operators when using it as a dynamic cast as I've shown in my question above.
One solution I found is to use System.Web.Helpers.Json, this implementation allows you to do what I'm trying to do above without running into the exception that JSON.NET throws because the way it evaluates the members at runtime leading to a simple way to access members of dynamic JSON structures. Plus you don't need to reference Value
for a member, it's implicit.
using System.Web.Helpers.Json
dynamic jsonMeta = Json.Decode(jsonString);
string gVal = jsonMeta.a?.b?.c?.d?.e?.f?.g ?? ""
You however need to install the assemblies separately depending on which version of Visual Studio you're using (which is also required for JSON.NET). With VS 2019, it's very easy to install it with a single click through the IDE error assistant. More details about it here: Where can I find System.Web.Helpers, System.Web.WebPages, and System.Web.Razor?
The limitation of Json.Decode
is that it cannot handle duplicate keys (throws an exception) and also has a maximum limit on then number of characters it can parse (MaxJsonLength error) which can be inconvenient to fix.