'Converting JObject to a dynamic object

I am calling a REST endpoint from C# and I am receiving json which gets serialized into an object. One of the properties on this object is a dynamic property. The value of the dynamic property is set as a anonymous object on the server site like this:

myObject.MyDynamicProp = new { Id = "MyId2134", Name = "MyName" };

On the client site the value of the dynamic property from the json serialization is a JObject containing the following value:

{{
  "id": "MyId2134",
  "Name": "MyName"
}}

I would have expected to be able to access the properties like this:

var s = myObject.MyDynamicProp.Name;

but it does not find the Name property instead I have to get the value like this:

var s = myObject.MyDynamicProp["Name"].Value;

I tried converting the JObject into a dynamic object like this but it returns JObject:

var dyn = myObject.MyDynamicProp.ToObject<dynamic>();

How can I convert the dynamic property value such that I can call its properties directly?

var s = myObject.MyDynamicProp.Name;

UPDATE ...

I ran the following

 dynamic d = JsonConvert.DeserializeObject("{\"MyDynamicProp\": {\"id\": \"MyId2134\", \"Name\": \"MyName\"}}");
 string name = d.MyDynamicProp.Name;

Which gives me the following the error:

 {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:    `Newtonsoft.Json.Linq.JObject' does not contain a definition for `MyDynamicProp'
  at Microsoft.Scripting.Interpreter.ThrowInstruction.Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) [0x00027]

I would like to add that this is an Xamarin iOS project and the code is located in a PCL library.


I assumed there was a problem with my code but it looks like it is not possible to use dynamic types within a Xamarin iOS project. https://developer.xamarin.com/guides/ios/advanced_topics/limitations/



Solution 1:[1]

It is actually quite easy. Instead of using var use dynamic on your JObject and you will be fine:

dynamic do = myObject.MyDynamicProp;

string name = do.Name;

From your fragment:

dynamic d = JsonConvert.DeserializeObject("{\"MyDynamicProp\": {\"id\": \"MyId2134\", \"Name\": \"MyName\"}}");
string name = d.MyDynamicProp.Name;

Console.WriteLine(name); // writes MyName

Why this works: As Richard explained, JObject derives indirectly from JToken which implements IDynamicMetaObjectProvider. It is that interface that allows dynamic to work.

Solution 2:[2]

create a linker.xml file inside android and BuildAction to linkDescription

then paste the below code

<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="Mono.Android">
    <type fullname="Xamarin.Android.Net.AndroidClientHandler" preserve="all" />
  </assembly>
    
    
    <assembly fullname="mscorlib"></assembly>
        
    <assembly fullname="System.Core"></assembly> 
        <assembly fullname="System.Runtime.Serialization"> </assembly> 
    <assembly fullname="Newtonsoft.Json"></assembly>
 \
    <assembly fullname="System.Reactive.Linq"></assembly> 
    <assembly fullname="System.Reactive.Interfaces"></assembly> 
 
    <assembly fullname="System.Xml"></assembly> 
        
   <assembly fullname="Xamarin.Forms.Core"></assembly>
</linker>

Solution 3:[3]

Use:

var expanded = JsonConvert.DeserializeObject<ExpandoObject>("{ ... }");
dynamic dynamicData = expanded;

The reason that the Patrick Hofman's answer won't work is because some compiler magic is causing JsonConvert.DeserializeObject<dynamic> to return a JObject. I dont know why this is the case, but your dynamic object is actually secretly a JObject. That is why the program throws a RuntimeBinderException saying that JObject doesn't contain the dynamic property when you try to call it with d.MyDynamicProp.

The solution that I presented fixes that by making sure it successfully deserializes as an ExpandoObject (which is what the dynamic type effectively is), then use the next line to cast the ExpandoObject into dynamic, which works.

NOTE: MY CODE IS 2 LINES FOR A REASON. THE CODE BELOW WILL NOT WORK

dynamic dynamicData = JsonConvert.DeserializeObject<ExpandoObject>("{ ... }");

This code will get 'optimized' and attempt to cast directly to a dynamic type, resulting in the previously mentioned error.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 vishnu t
Solution 3 user3814158