将JSON反序列化为C#动态对象?

有没有一种方法可以将JSON内容反序列化为C#4动态类型?跳过创建一堆类以使用会很好DataContractJsonSerializer

回答:

如果您愿意依赖该System.Web.Helpers程序集,则可以使用Json该类:

dynamic data = Json.Decode(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; // 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)

以上是 将JSON反序列化为C#动态对象? 的全部内容, 来源链接: utcz.com/qa/416927.html

回到顶部