erichunt erichunt - 1 year ago 48
C# Question

ASP.NET getting indexed values when deserializing JSON into a dynamic object

So I have a JSON string that I am passing from an AJAX call to my controller. I have a list of indexed values that I am passing into a dynamic object.

I deserialize the JSON with


This is the output from that dynamic object:

"RolePermissions[0].RolePermissionId": "269",
"RolePermissions[0].HasAccess": "false",
"RolePermissions[1].RolePermissionId": "270",
"RolePermissions[1].HasAccess": "false",
"RolePermissions[2].RolePermissionId": "271",
"RolePermissions[2].HasAccess": "true",
"RolePermissions[3].RolePermissionId": "272",
"RolePermissions[3].HasAccess": "false"

When I try to access the a property of the object with


I get a RuntimeBinderException. I have tried to use JObject.Parse, which works great, but for some reason, the values in the array become out of order.

Any help would be greatly appreciated. Thanks!

dbc dbc
Answer Source

When you try to do RolePermissions[0].RolePermissionId you are trying to access a nested collection containing an object with a property RolePermissionId at index 0. But your JSON doesn't represent a hierarchy of objects, it represents a single flat object with key/value pairs whose keys contain periods and brackets. Since c# identifiers don't allow such characters so you have no way to access such property values using dynamic directly.

Instead, your options include:

  1. Take advantage of the fact that JsonConvert.DeserializeObject<dynamic>(s) actually returns a JObject and use its dictionary indexer:

    var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
    var rolePermissionId = (string)ssObj["RolePermissions[0].RolePermissionId"];
  2. If you prefer a slightly more typed solution, you could deserialize to a Dictionary<string, dynamic>:

    var ssDict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(s);
    var rolePermissionId = (string)ssDict["RolePermissions[0].RolePermissionId"];
  3. Or for a much more statically typed solution, parse explicitly to a JObject and use LINQ to JSON:

    var jObj = JObject.Parse(s);
    var rolePermissionId = (string)jObj["RolePermissions[0].RolePermissionId"];

Sample fiddle showing the various options.