c# - 使用动态变量解析 JSON block

标签 c# json

我正在从 URL 中获取 JSON 对象并使用 JSON.NET 对其进行解析。我能够很好地解析具有已定义变量的数据 block ,但是当涉及到 var:value 的随机收集时,我被卡住了。

示例(松散类型):

{"FNAME":"joe","LNAME":"doe",<br/> "BodyType":{"height":180,"weight":"200","race":"white","hair":"black"},<br/> "BELONGINGS":{"shirt":"black","Money":15,"randomThing":"anyvar"},<br/> "Signs":{"tattoo":0,"scar":"forehead","glasses":"dorky"}<br/> }

我要把它转换到

Class Person<br/> {<br/> public string FNAME;<br/> public string LNAME;<br/> public BodyType bodyType;<br/> public ????? belongings;<br/> public ????? signs;<br/> }<br/> 如果我无法预测元素和标志的属性,我该如何处理它们?

最佳答案

有两种在运行时不知道内容的情况下处理它们的方法。

第一种方式是使用JSON.Net的JObject ,它将处理您提到的情况以及层次结构。

第二种方法是使用 System.Dynamic 的 ExpandoObject ,这是最近发布的 JSON.Net 新支持的。不幸的是,它不能很好地处理层次结构,但 JSON.Net 会返回到 JObject遇到时支持他们。出于您的目的,它可能更直接。

这是一个包含您提供的代码段和定义的示例。另请注意 ExpandoObject可直接转换为 IDictionary<string, object> ,而 JObject具有访问属性的显式方法。

人对应ExpandoObject ,而JPerson对应JObject .

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Dynamic;

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

namespace YourFavoriteNamespace
{
    public class JPerson
    {
        public string FNAME;
        public string LNAME;
        public BodyType bodyType;
        public JObject belongings;
        public JObject signs;
    }

    public class Person
    {
        public string FNAME;
        public string LNAME;
        public BodyType bodyType;
        public ExpandoObject belongings;
        public ExpandoObject signs;
    }

    public class BodyType
    {
        public int height;
        public int weight;
        public string race;
        public string hair;
    }

    class Program
    {
        static void DumpDynamic(dynamic d)
        {
            IDictionary<string, object> dynMap = (IDictionary<string, object>)d;
            foreach (string key in dynMap.Keys)
            {
                Console.WriteLine("  {0}={1} (type {2})", key, dynMap[key], null == dynMap[key] ? "null" : dynMap[key].GetType().Name);
            }
        }

        static void DumpJProperties(JObject jo)
        {
            var props = jo.Properties();
            foreach (JProperty prop in props)
            {
                Console.WriteLine("  {0}={1} (type {2})", prop.Name, prop.Value, null == prop.Value ? "null" : prop.Value.GetType().Name);
            }
        }

        static void DumpPerson(Person p)
        {
            Console.WriteLine("Person");
            Console.WriteLine("  FNAME={0}", p.FNAME);
            Console.WriteLine("  LNAME={0}", p.LNAME);
            Console.WriteLine("Person.BodyType");
            Console.WriteLine("  height={0}", p.bodyType.height);
            Console.WriteLine("  weight={0}", p.bodyType.weight);
            Console.WriteLine("  race  ={0}", p.bodyType.race);
            Console.WriteLine("  hair  ={0}", p.bodyType.hair);
            Console.WriteLine("Person.belongings");
            DumpDynamic(p.belongings);
            Console.WriteLine("Person.signs");
            DumpDynamic(p.signs);
        }

        static void DumpJPerson(JPerson p)
        {
            Console.WriteLine("Person");
            Console.WriteLine("  FNAME={0}", p.FNAME);
            Console.WriteLine("  LNAME={0}", p.LNAME);
            Console.WriteLine("Person.BodyType");
            Console.WriteLine("  height={0}", p.bodyType.height);
            Console.WriteLine("  weight={0}", p.bodyType.weight);
            Console.WriteLine("  race  ={0}", p.bodyType.race);
            Console.WriteLine("  hair  ={0}", p.bodyType.hair);
            Console.WriteLine("Person.belongings");
            DumpJProperties(p.belongings);
            Console.WriteLine("Person.signs");
            DumpJProperties(p.signs);
        }

        static void DoSimplePerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":\"dorky\"}}";
            Person p = JsonConvert.DeserializeObject<Person>(initJson);
            DumpPerson(p);
            Console.ReadLine();
        }

        static void DoComplexPerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":[\"dorky\",\"hipster\"]}}";
            Person p = JsonConvert.DeserializeObject<Person>(initJson);
            DumpPerson(p);
            Console.ReadLine();
        }

        static void DoJPerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":\"dorky\"}}";
            JPerson p = JsonConvert.DeserializeObject<JPerson>(initJson);
            DumpJPerson(p);
            Console.ReadLine();
        }

        static void Main(string[] args)
        {
            DoSimplePerson();
            DoComplexPerson();
            DoJPerson();
        }
    }
}

关于c# - 使用动态变量解析 JSON block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5628374/

相关文章:

c# - 使用网络浏览器控件进行自动登录时如何避免安全页面?

c# - 使用不同的用户名连接到同一服务器

c# - 查找每个月的第三个星期日出现在给定的两个日期之间

c# - 从 C# 调用 C 函数,传递包含指针的结构

Json 架构在 if 条件上添加属性

c# - Unity3d 可视化脚本框架在幕后如何工作?

javascript - 使用 JSON 数据类型向来自 Ajax 的新数据添加新类

android - 找不到 logcat 提示的 JSON 解析错误

c# - 将 TimeSpan 值序列化和反序列化为 Object 类型的属性

json - ASN.1 vs JSON 什么时候适合使用它们?