C#关于接收到的JSON多重结构的反序列化问题
我从其它网站获取信息,接收到一串JSON,我只想取其distance中的值,JavaScriptSerializerjss=newJavaScriptSerializer...
我从其它网站获取信息,接收到一串JSON,我只想取其distance中的值, JavaScriptSerializer jss=new JavaScriptSerializer();
Dictionary<string, object> ar = (Dictionary<string, object>)jss.DeserializeObject(str);
foreach (var _a in ar)
{
if (_a.Key == "result")
foreach (var _b in (Dictionary<string, object>)_a.Value)///此处断点显示的是 _a.Value count=4可以强类型转换
{
if (_b.Key == "routes")
{
foreach (var _c in (Dictionary<string, object>)_b.Value)//此处断点显示 _b.Value object[1] 这里转换失败,退出
{
foreach (var _d in (Dictionary<string, object>)_c.Value)
if (_d.Key == "distance")
str = Convert.ToString(_d.Value);
}
}
}
}
请教 foreach (var _c in (Dictionary<string, object>)_b.Value)这个地方要怎么修改? 展开
Dictionary<string, object> ar = (Dictionary<string, object>)jss.DeserializeObject(str);
foreach (var _a in ar)
{
if (_a.Key == "result")
foreach (var _b in (Dictionary<string, object>)_a.Value)///此处断点显示的是 _a.Value count=4可以强类型转换
{
if (_b.Key == "routes")
{
foreach (var _c in (Dictionary<string, object>)_b.Value)//此处断点显示 _b.Value object[1] 这里转换失败,退出
{
foreach (var _d in (Dictionary<string, object>)_c.Value)
if (_d.Key == "distance")
str = Convert.ToString(_d.Value);
}
}
}
}
请教 foreach (var _c in (Dictionary<string, object>)_b.Value)这个地方要怎么修改? 展开
3个回答
展开全部
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);
展开全部
直接用烦序列化类,不要自己去写,实在子节点深了 用正则截取, 或截取后反序列化
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
运行的时候鼠标放在_b上面,看究竟是什么类型。
追问
object类型,现在是用实体类做到了,但还是想不用实体类怎么达到这目的
追答
不知道你说的实体类指什么?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询