如何在C#中从JSON对象中读取数据

26 浏览
0 Comments

如何在C#中从JSON对象中读取数据

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

admin 更改状态以发布 2023年5月24日
0
0 Comments

使用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;

文档:使用dynamic查询JSON

0
0 Comments

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

dynamic data = Json.Decode(json);

它作为MVC框架的一个附加下载包含在.NET 4框架中。 如果 helpful 的话,请给Vlad点赞!然而,如果您不能假定客户端环境包括此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 dictionary, 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(arrayList.Cast>().Select(x => new DynamicJsonObject(x))) 
                    : new List(arrayList.Cast());
            }
            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)

0