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类型,现在是用实体类做到了,但还是想不用实体类怎么达到这目的
追答不知道你说的实体类指什么?