1、使用Json.NET实现
可以使用 Json.NET(也称为 Newtonsoft.Json)来将 JSON 字符串反序列化为 dynamic
类型对象。 Json.NET 是一个非常流行的 JSON 处理库,它支持强类型和动态类型的反序列化。
文档:https://www.newtonsoft.com/json/help/html/QueryJsonDynamic.htm
dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = stuff.Name;
string address = stuff.Address.City;
或
//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;
2、使用System.Web.Helpers.Json实现
包含在System.Web.Helpers程序集(.NET 4.0)中。使用 System.Web.Helpers.Json
来反序列化 JSON 字符串为 dynamic
类型对象的方法非常简单。System.Web.Helpers.Json
提供了静态方法 Json.Decode
,可以将 JSON 字符串解析为 dynamic
类型的对象。
var dynamicObject = Json.Decode("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = stuff.Name;
string address = stuff.Address.City;
3、使用JavaScriptSerializer实现
.Net 4.0内置的一个库,可以使用 JavaScriptSerializer
类将 JSON 字符串反序列化为动态类型(dynamic
)对象。JavaScriptSerializer
是一个简单的内置工具,适用于较小的 JSON 数据反序列化。
using System.Web.Script.Serialization;
JavaScriptSerializer jss = new JavaScriptSerializer();
var d = jss.Deserialize<dynamic>(str);
或
using System.Web.Script.Serialization;
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"];
4、使用JsonFx实现
使用 JsonFx 将 JSON 字符串反序列化为 dynamic
类型的对象可以通过 JsonReader
实现。
文档:https://github.com/jsonfx/jsonfx
var reader = new JsonReader(); var writer = new JsonWriter(); string input = @"{ ""foo"": true, ""array"": [ 42, false, ""Hello!"", null ] }"; dynamic output = reader.Read(input); Console.WriteLine(output.array[0]); // 42 string json = writer.Write(output); Console.WriteLine(json); // {"foo":true,"array":[42,false,"Hello!",null]}
5、使用自定义DynamicJsonConverter类实现
需要引用System.Web.Extensions,要将 JSON 字符串反序列化为 dynamic
类型的对象,可以通过自定义一个 DynamicJsonConverter
来实现。这个自定义的转换器可以与 JsonSerializer
一起使用。
DynamicJsonConverter类代码:
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) })); } } 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; } } }
使用示例代码:
dynamic data = serializer.Deserialize("{ \"Items\":[ { \"Name\":\"Apple\", \"Price\":12.3 }, { \"Name\":\"Grape\", \"Price\":3.21 } ], \"Date\":\"21/11/2010\" }", 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)