将JSON反序列化为C#的动态对象?
将JSON反序列化为C#的动态对象?
有没有一种方法可以将JSON内容反序列化为C#动态类型? 这样就可以省略创建一堆类以使用DataContractJsonSerializer
了。
admin 更改状态以发布 2023年5月23日
使用 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;
同时使用 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;
如果您愿意依赖于 System.Web.Helpers
程序集,那么您可以使用 Json
类:
dynamic data = Json.Decode(json);
它作为 MVC 框架的一个附加下载包含在 .NET 4 框架中。如果有帮助,请一定给 Vlad 点赞!但如果您不能假设客户端环境包含此 DLL,则请继续阅读。
这里提供了一种替代反序列化方法。我稍微修改了代码来修复一个 bug 并符合我的编码风格。您只需要使用此代码,并从您的项目引用 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(IDictionarydictionary, Type type, JavaScriptSerializer serializer) { if (dictionary == null) throw new ArgumentNullException("dictionary"); return type == typeof(object) ? new DynamicJsonObject(dictionary) : null; } public override IDictionary Serialize(object obj, JavaScriptSerializer serializer) { throw new NotImplementedException(); } public override IEnumerable SupportedTypes { get { return new ReadOnlyCollection (new List (new[] { typeof(object) })); } } #region Nested type: DynamicJsonObject private sealed class DynamicJsonObject : DynamicObject { private readonly IDictionary _dictionary; public DynamicJsonObject(IDictionary 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 ) { new DynamicJsonObject((IDictionary )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 ) new DynamicJsonObject((IDictionary )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 ; if (dictionary != null) return new DynamicJsonObject(dictionary); var arrayList = result as ArrayList; if (arrayList != null && arrayList.Count > 0) { return arrayList[0] is IDictionary ? new List
您可以像这样使用它:
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; // 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)