C#反序列化解析json为动态对象

C#反序列化解析json为动态对象两种方法。

方法一:System.Web.Helpers.Json

最简洁的方式使用System.Web.Helpers.Json ,它的Decode方法返回一个动态对象,我们可以根据需要遍历它。

使用很简洁:

var dynamicObject = Json.Decode(jsonString);

System.Web.Helpers.dll 依赖于.NET 4.0,可以与ASP.NET MVC 3一起安装。

方法二:只依赖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));

更多参考文章http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx。


版权声明:著作权归作者所有。

相关推荐

C#对List的元素按属性排序

C#对List元素排序有几种方法。方法一、使用LinqList<User> sortedList = list.OrderBy(o=>o.ID).ToList();如果按降序排序,可以使用OrderByDescending方法:List<User> sortedList = list.OrderByDescending(o=>o.ID).ToList();方法二

C#给文档注释添加换行

错误用法:使用<br />/// 第一行 /// <br /> /// 第二行 显示出来没有效果。正确做法:使用<para>/// <summary> /// <para>第一行</para> /// <para>第二行</par

C#对DataTable做LINQ查询

我们是不能直接对DataTable做LINQ查询,DataRowCollection是没有实现IEnumerable<T>。有一些方法可以间接实现对DataTable执行LINQ查询。AsEnumerable()使用DataTable的扩展AsEnumerable(),把DataTable转换为IEnumerable<DataRow>。var results&nb

C#计算用户年龄

此方法仅用于简单计算年龄,不适用于计算虚岁public static int GetAge(DateTime birthDate) {     DateTime now = DateTime.Now;      int age&n

Android使用Kotlin新特性Parcelize序列化对象

Android对对象序列化主要有两种方式:Serializable和Parcelable。Serializable实际是使用Java的放射机制对对象做序列化和反序列化,其性能远低于使用Parcelable。但是使用Java写的Parcelable有点繁琐,需要我们实现Parcelable接口,手写很多模板代码。Java版Parcelable示例public class User

[译]Swift 4 解析JSON最终指南

Swift 4和Foundation终于回答了如何用Swift来解析JSON的问题。目前已经有了许多优秀的库,但是看到一个全支持的解决方案是非常令人耳目一新的,它不仅易于使用且也提供了对复杂场景进行编码和解码所需的定制。值得注意的是,这里讨论的所有内容都适用于所有Encoder/Decoder实现,例如包括PropertyListEncoder。 如果你需要类似XML这样不同的