/*--------------------------------------------------------------------------* DynamicJson* ver 1.2.0.0 (May. 21th, 2010)** created and maintained by neuecc * licensed under Microsoft Public License(Ms-PL)* http://neue.cc/* http://dynamicjson.codeplex.com/*--------------------------------------------------------------------------*/namespace Microshaoft{ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.Serialization.Json; using System.Text; using System.Xml; using System.Xml.Linq; public class DynamicJson : DynamicObject { public object _value = null; public object Value { get { if (_isValue) { return _value; } else { throw new Exception("It is not a Value!"); } } } private bool _isValue = false; public bool IsValue { get { return _isValue; } } public T GetValue () { return (T) Value; } public DynamicJson this[string key] { get { var x = xml.Element(key); var value = default(dynamic); var r = XElementToDynamicJson(x, out value); if (r == null) { _value = value; r = this; _isValue = true; } return r; } } public DynamicJson this[int index] { get { var x = xml .Elements() .ElementAt(index); var value = default(dynamic); var r = XElementToDynamicJson(x, out value); if (r == null) { _value = value; r = this; _isValue = true; } return r; } } private DynamicJson XElementToDynamicJson ( XElement x , out dynamic value ) { DynamicJson r = null; if (TryGet(x, out value)) { r = value as DynamicJson; } else { throw new Exception("no member"); } return r; } private enum JsonType { @string, number, boolean, @object, array, @null } // public static methods /// from JsonSring to DynamicJson public static dynamic Parse(string json) { return Parse(json, Encoding.Unicode); } /// from JsonSring to DynamicJson public static dynamic Parse(string json, Encoding encoding) { using (var reader = JsonReaderWriterFactory.CreateJsonReader(encoding.GetBytes(json), XmlDictionaryReaderQuotas.Max)) { return ToValue(XElement.Load(reader)); } } /// from JsonSringStream to DynamicJson public static dynamic Parse(Stream stream) { using (var reader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max)) { return ToValue(XElement.Load(reader)); } } /// from JsonSringStream to DynamicJson public static dynamic Parse(Stream stream, Encoding encoding) { using (var reader = JsonReaderWriterFactory.CreateJsonReader(stream, encoding, XmlDictionaryReaderQuotas.Max, _ => { })) { return ToValue(XElement.Load(reader)); } } /// create JsonSring from primitive or IEnumerable or Object({public property name:property value}) public static string Serialize(object obj) { return CreateJsonString(new XStreamingElement("root", CreateTypeAttr(GetJsonType(obj)), CreateJsonNode(obj))); } // private static methods private static dynamic ToValue(XElement element) { var type = (JsonType)Enum.Parse(typeof(JsonType), element.Attribute("type").Value); switch (type) { case JsonType.boolean: return (bool)element; case JsonType.number: return (double)element; case JsonType.@string: return (string)element; case JsonType.@object: case JsonType.array: return new DynamicJson(element, type); case JsonType.@null: default: return null; } } private static JsonType GetJsonType(object obj) { if (obj == null) return JsonType.@null; switch (Type.GetTypeCode(obj.GetType())) { case TypeCode.Boolean: return JsonType.boolean; case TypeCode.String: case TypeCode.Char: case TypeCode.DateTime: return JsonType.@string; case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.SByte: case TypeCode.Byte: return JsonType.number; case TypeCode.Object: return (obj is IEnumerable) ? JsonType.array : JsonType.@object; case TypeCode.DBNull: case TypeCode.Empty: default: return JsonType.@null; } } private static XAttribute CreateTypeAttr(JsonType type) { return new XAttribute("type", type.ToString()); } private static object CreateJsonNode(object obj) { var type = GetJsonType(obj); switch (type) { case JsonType.@string: case JsonType.number: return obj; case JsonType.boolean: return obj.ToString().ToLower(); case JsonType.@object: return CreateXObject(obj); case JsonType.array: return CreateXArray(obj as IEnumerable); case JsonType.@null: default: return null; } } private static IEnumerable CreateXArray (T obj) where T : IEnumerable { return obj.Cast