Created
May 12, 2011 20:46
-
-
Save AHartTN/969404 to your computer and use it in GitHub Desktop.
My Dynamic JSON object converter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) })); } | |
} | |
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; | |
} | |
var dictionary = result as IDictionary<string, object>; | |
if (dictionary != null) | |
{ | |
result = new DynamicJsonObject(dictionary); | |
return true; | |
} | |
var arrayList = result as ArrayList; | |
if (arrayList != null && arrayList.Count > 0) | |
{ | |
if (arrayList[0] is IDictionary<string, object>) | |
result = new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x))); | |
else | |
result = new List<object>(arrayList.Cast<object>()); | |
} | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment