如果您愿意依赖该
System.Web.Helpers程序集,则可以使用
Json该类:
dynamic data = Json.Depre(json);
它包含在MVC框架中,作为对.NET
4框架的额外下载。如果有帮助,请务必给弗拉德投票!但是,如果您不能假定客户端环境包括此DLL,请继续阅读。
这里提出了另一种反序列化方法。我稍稍修改了代码以修复错误并适合我的编码风格。您需要的只是此代码和
System.Web.Extensions项目的引用:
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}您可以像这样使用它:
string json = ...;var serializer = new JavascriptSerializer();serializer.RegisterConverters(new[] { new DynamicJsonConverter() });dynamic obj = serializer.Deserialize(json, typeof(object));因此,给定一个JSON字符串:
{ "Items":[ { "Name":"Apple", "Price":12.3 }, { "Name":"Grape", "Price":3.21 } ], "Date":"21/11/2010"}以下代码将在运行时运行:
dynamic data = serializer.Deserialize(json, typeof(object));data.Date; // "21/11/2010"data.Items.Count; // 2data.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)



