问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C#关于接收到的JSON多重结构的反序列化问题

发布网友 发布时间:2022-04-24 04:41

我来回答

3个回答

热心网友 时间:2022-04-24 06:10

JavaSerializer反序列化一个不知其类型的对象时,每一个属性的值都只可能是两种类型之一:Dictionary<string,object>和 Array,其中被反序列化为Array的值在Json中本就是的数组。你的代码中没有考虑这一点所以异常了,多判断一下类型即可。


此外我还写了个简单的辅助类,应该能省去你一层层foreach的麻烦。该辅助类做了一点点优化,区分处理了字典和数组,不再需要遍历字典的key。


使用时把要访问的属性的”全路径“填进去就好,数组成员使用[ ]形式。如果指向不存在的属性则返回null。


例 var result = NonTypeObjectReader.GetValue(obj, "prop.children[0].innerProp"


    class NonTypeObjectReader
    {
        public static object GetValue(object obj, string expression)
        {
            var stack = GetExpQueue(expression);
            if (stack.Count > 0)
            {
                return GetValueInner(obj, stack);
            }
            return null;
        }
        private static object GetValueInner(object obj, Queue<Tuple<string, bool>> stack)
        {
            if (stack.Count > 0)
            {
                var tup = stack.Dequeue();
                if (!tup.Item2)
                {
                    var dictObj = obj as IDictionary<string, object>;
                    if (dictObj != null && dictObj.ContainsKey(tup.Item1))
                    {
                        return GetValueInner(dictObj[tup.Item1], stack);
                    }
                }
                else if (!(obj is IDictionary<string, object>))
                {
                    var index = int.Parse(tup.Item1);
                    var arrObj = obj as Array;
                    if (arrObj != null && arrObj.Length > index)
                    {
                        return GetValueInner(arrObj.GetValue(index), stack);
                    }
                }
                return null;
            }
            return obj;
        }
        private static Queue<Tuple<string, bool>> GetExpQueue(string expression)
        {
            var rtnStack = new Queue<Tuple<string, bool>>();
            StringBuilder propName = new StringBuilder();
            var nextSaveIsIndex = false;
            for (var cursor = 0; cursor < expression.Length; cursor++)
            {
                var ch = expression[cursor];
                if (ch != '.' && ch != '[' && ch != ']')
                {
                    propName.Append(ch);
                }
                else if (propName.Length > 0)
                {
                    rtnStack.Enqueue(new Tuple<string, bool>(propName.ToString(), nextSaveIsIndex));
                    propName.Clear();
                    nextSaveIsIndex = ch == '[';
                }
            }
            if (propName.Length > 0)
            {
                rtnStack.Enqueue(new Tuple<string, bool>(propName.ToString(), false));
            }
            return rtnStack;
        }
    }


测试代码:

    var serializer = new JavaScriptSerializer();
    var rawObj = new
    {
        Prop1 = 1,
        Prop2 = "hello",
        Children = new[]
        {
            new
            {
                InnerProp = "1",
                Sub = new object[]{"string",2016}
            },
            new 
            {
                InnerProp="2",
                Sub = new object[]{DateTime.Now,2.5}
            }
        }
    };
    var jsonStr = serializer.Serialize(rawObj);
    var obj = serializer.DeserializeObject(jsonStr);
    var value = NonTypeObjectReader.GetValue(obj, "Children[0].Sub[1]");
    Debug.Assert(value is int && (int)value == 2016);

热心网友 时间:2022-04-24 07:28

直接用烦序列化类,不要自己去写,实在子节点深了 用正则截取, 或截取后反序列化

热心网友 时间:2022-04-24 09:03

运行的时候鼠标放在_b上面,看究竟是什么类型。追问object类型,现在是用实体类做到了,但还是想不用实体类怎么达到这目的

追答不知道你说的实体类指什么?

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
5数字寓意是什么意思 如何在 iPhone14上恢复已删除的照片? 红井源 醇香胡麻油 2.5L-购买最佳价格 python如何实现修改当前文件夹下所有文件名称? python遍历输出所有文件 用Python遍历指定文件夹下所有文件 Python:读取指定路径下的文件,含子文件夹,可指定文件类型 谁有治疗网瘾的好方法? 孩子有网瘾又叛逆怎么办 退伍证名字错了怎么办 72伏的电动四轮车须多少安的断路器? 建宏中天山茶油有什么作用? 有特别点的女宝宝名字吗 72伏的电动车应该是多少安的电流 请帮我家女宝宝取个特别点的名字,姓郑,阳历6月30号…下午2点50分出生,蛇年,谢谢! 三角函数计算公式基本内容 高中的三角函数大概有哪些概念?公式?高考考点是什么? 帮女宝宝取个特别点名字 72伏的电动车电流是多大? 暖气片如何放气?什么情况下暖气片需要放气? 三角函数12个基本公式 暖气片怎么放气?壁挂暖气片怎么放气 河北省18年的精神文明奖有没有发的呀?发多少钱? 河北省企业退休人员为什么没有精神文明奖 河北省2015精神文明奖 河北省的特岗教师精神文明奖发放是什么标准?为什么我们发的是第一年1000,第二年2000呢? 2021年承德县的精神文明奖什么时候发? 5000w电磁炉怎么接线啊 为什么驻河北省的央企没有精神文明奖。而河北省的其他事业单位有? 石家庄2022年精神文明奖有吗 皮肤稍黑的动漫女生 动漫中的腹黑女生你还知道哪些? 动漫中有哪些女生的皮肤是偏黑的? 不愿再背锅,冯绍峰憋不住爆出不娶倪妮真相,我们是不是错怪他了?_百度... 经历了三年的恋情,也为倪妮买下豪宅,冯绍峰坦言当初分手的原因,啥情况... 冯绍峰和倪妮同居3年之久,为何转身闪婚赵丽颖,如今为什么又离婚?_百度... 冯绍峰和井柏然都曾是她前男友,为什么如今倪妮目前还是单身呢? 公子哥冯绍峰,为何会放弃相爱3年的倪妮,选择邻家女孩赵丽颖? 冯绍峰为什么放弃交往3年的倪妮,转身娶了赵丽颖呢? 冯绍峰和倪妮的合照,对比冯绍峰和前妻的合照,你有什么发现? 倪妮冯绍峰在一起几年谈了多久恋爱 为什么分道扬镳 倪妮在撩也撩不动冯绍峰,这是为啥? 与赵丽颖领证5个月产子,放弃倪妮成“妻管严”的冯绍峰,后悔了吗? 出自于哪部游戏 有一款游戏,和节奏大师的星动模式有点像,但它是带舞蹈动作的,是什么? 有没有练手速的手机游戏 给我介绍几个好玩的手机游戏和电脑游戏 啥手机游戏好玩 有没有好玩的 安卓游戏推荐下 有没类似节奏大师的音乐游戏