.net - Deserialize JSON into C# dynamic object?

ID : 1265

viewed : 167

Tags : c#.netjsonserializationdynamicc#





Top 5 Answer for .net - Deserialize JSON into C# dynamic object?

vote vote

100

If you are happy to have a dependency upon the System.Web.Helpers assembly, then you can use the Json class:

dynamic data = Json.Decode(json); 

It is included with the MVC framework as an additional download to the .NET 4 framework. Be sure to give Vlad an upvote if that's helpful! However if you cannot assume the client environment includes this DLL, then read on.


An alternative deserialisation approach is suggested here. I modified the code slightly to fix a bug and suit my coding style. All you need is this code and a reference to System.Web.Extensions from your project:

using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic; using System.Linq; using System.Text; using System.Web.Script.Serialization;  public sealed class DynamicJsonConverter : JavaScriptConverter {     public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)     {         if (dictionary == null)             throw new ArgumentNullException("dictionary");          return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;     }      public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)     {         throw new NotImplementedException();     }      public override IEnumerable<Type> SupportedTypes     {         get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }     }      #region Nested type: DynamicJsonObject      private sealed class DynamicJsonObject : DynamicObject     {         private readonly IDictionary<string, object> _dictionary;          public DynamicJsonObject(IDictionary<string, object> dictionary)         {             if (dictionary == null)                 throw new ArgumentNullException("dictionary");             _dictionary = dictionary;         }          public override string ToString()         {             var sb = new StringBuilder("{");             ToString(sb);             return sb.ToString();         }          private void ToString(StringBuilder sb)         {             var firstInDictionary = true;             foreach (var pair in _dictionary)             {                 if (!firstInDictionary)                     sb.Append(",");                 firstInDictionary = false;                 var value = pair.Value;                 var name = pair.Key;                 if (value is string)                 {                     sb.AppendFormat("{0}:\"{1}\"", name, value);                 }                 else if (value is IDictionary<string, object>)                 {                     new DynamicJsonObject((IDictionary<string, object>)value).ToString(sb);                 }                 else if (value is ArrayList)                 {                     sb.Append(name + ":[");                     var firstInArray = true;                     foreach (var arrayValue in (ArrayList)value)                     {                         if (!firstInArray)                             sb.Append(",");                         firstInArray = false;                         if (arrayValue is IDictionary<string, object>)                             new DynamicJsonObject((IDictionary<string, object>)arrayValue).ToString(sb);                         else if (arrayValue is string)                             sb.AppendFormat("\"{0}\"", arrayValue);                         else                             sb.AppendFormat("{0}", arrayValue);                      }                     sb.Append("]");                 }                 else                 {                     sb.AppendFormat("{0}:{1}", name, value);                 }             }             sb.Append("}");         }          public override bool TryGetMember(GetMemberBinder binder, out object result)         {             if (!_dictionary.TryGetValue(binder.Name, out result))             {                 // return null to avoid exception.  caller can check for null this way...                 result = null;                 return true;             }              result = WrapResultObject(result);             return true;         }          public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)         {             if (indexes.Length == 1 && indexes[0] != null)             {                 if (!_dictionary.TryGetValue(indexes[0].ToString(), out result))                 {                     // return null to avoid exception.  caller can check for null this way...                     result = null;                     return true;                 }                  result = WrapResultObject(result);                 return true;             }              return base.TryGetIndex(binder, indexes, out result);         }          private static object WrapResultObject(object result)         {             var dictionary = result as IDictionary<string, object>;             if (dictionary != null)                 return new DynamicJsonObject(dictionary);              var arrayList = result as ArrayList;             if (arrayList != null && arrayList.Count > 0)             {                 return arrayList[0] is IDictionary<string, object>                      ? new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x)))                      : new List<object>(arrayList.Cast<object>());             }              return result;         }     }      #endregion } 

You can use it like this:

string json = ...;  var serializer = new JavaScriptSerializer(); serializer.RegisterConverters(new[] { new DynamicJsonConverter() });  dynamic obj = serializer.Deserialize(json, typeof(object)); 

So, given a JSON string:

{   "Items":[     { "Name":"Apple", "Price":12.3 },     { "Name":"Grape", "Price":3.21 }   ],   "Date":"21/11/2010" } 

The following code will work at runtime:

dynamic data = serializer.Deserialize(json, typeof(object));  data.Date; // "21/11/2010" data.Items.Count; // 2 data.Items[0].Name; // "Apple" data.Items[0].Price; // 12.3 (as a decimal) data.Items[1].Name; // "Grape" data.Items[1].Price; // 3.21 (as a decimal) 
vote vote

87

It's pretty simple using Json.NET:

dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");  string name = stuff.Name; string address = stuff.Address.City; 

Also using Newtonsoft.Json.Linq:

dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");  string name = stuff.Name; string address = stuff.Address.City; 

Documentation: Querying JSON with dynamic

vote vote

70

You can do this using System.Web.Helpers.Json - its Decode method returns a dynamic object which you can traverse as you like.

It's included in the System.Web.Helpers assembly (.NET 4.0).

var dynamicObject = Json.Decode(jsonString); 
vote vote

67

.NET 4.0 has a built-in library to do this:

using System.Web.Script.Serialization; JavaScriptSerializer jss = new JavaScriptSerializer(); var d = jss.Deserialize<dynamic>(str); 

This is the simplest way.

vote vote

51

Simple "string JSON data" to object without any third-party DLL file:

WebClient client = new WebClient(); string getString = client.DownloadString("https://graph.facebook.com/zuck");  JavaScriptSerializer serializer = new JavaScriptSerializer(); dynamic item = serializer.Deserialize<object>(getString); string name = item["name"];  //note: JavaScriptSerializer in this namespaces //System.Web.Script.Serialization.JavaScriptSerializer 

Note: You can also using your custom object.

Personel item = serializer.Deserialize<Personel>(getString); 

Top 3 video Explaining .net - Deserialize JSON into C# dynamic object?







Related QUESTION?