这是我的JSON回复:
{
"-JxpUA1eC_I3miJrdGGs": {
"company": "Microsoft",
"designation": "Chief Executive officer",
"email": "white@microsoft.com",
"name": "Nathan White",
"phone": "51342212333"
},
"-Jy5dki5KkgyxQBuDwNI": {
"bizcardData": {
"company": "Spotify",
"designation": "Designer",
"email": "komarapa@spotify.com",
"name": "Phani Komaravolu",
"phone": "5135921240"
},
"transData": {
"date": "15-08-31",
"location": "39.1395996,-84.5295417",
"tag": "sender",
"time": "22:05:38"
}}
}
我使用RestSharp将其反序列化为:
var resultList = SimpleJson.DeserializeObject<Dictionary<string, SingleCardDetails>>(content);
这是我的SingleCardDetails对象:
public class SingleCardDetails
{
public string Name { get; set; }
public string Company { get; set; }
public string Designation { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
我正在尝试使用它来迭代使用:
foreach (var card_details in resultList.Values) {
var name = card_details.Name;
var company = card_details.Company;
var designation = card_details.Designation;
var email = card_details.Email;
var phone = card_details.Phone;
}
但是这里的所有值如name,company等都是null。上面的代码有什么问题。我假设迭代有问题。请建议代码来解决这个问题。 谢谢!
答案 0 :(得分:1)
为了将数据反序列化为强类型对象,对象层次结构应该正确匹配。但是给定的JSON示例看起来就像在根元素下使用一些编码对象一样生成。我认为您可以使用动态反序列化来获取嵌套对象,而无需创建不必要的类型以解析JSON。
为了给你解决或快速指导。我将json.net与ExpandoObject一起使用。
我只是使用JObject方法来解析问题中给出的sample json
。在实际的scneario中,如果你有这样的对象的数组,你可以使用JArray。 JObject
解析提供给JObject
的任何字符串json。但JObject
无法直接投放到ExpandoObject
中,因此我正在使用来自源here的快速解决方法。以下是将JObject
转换为ExpandoObject
所需的方法。
public static object ConvertJTokenToObject(JToken token)
{
if (token is JValue)
{
return ((JValue)token).Value;
}
if (token is JObject)
{
ExpandoObject expando = new ExpandoObject();
(from childToken in ((JToken)token) where childToken is JProperty select childToken as JProperty).ToList().ForEach(property =>
{
((IDictionary<string, object>)expando).Add(property.Name, ConvertJTokenToObject(property.Value));
});
return expando;
}
if (token is JArray)
{
object[] array = new object[((JArray)token).Count];
int index = 0;
foreach (JToken arrayItem in ((JArray)token))
{
array[index] = ConvertJTokenToObject(arrayItem);
index++;
}
return array;
}
throw new ArgumentException(string.Format("Unknown token type '{0}'", token.GetType()), "token");
}
}
现在解析你的JSON首先简单地调用提供的JSON上的解析器。
dynamic result = JObject.Parse(JsonDataTest.SampleJson);
var expando = ConvertJTokenToObject(result) as IDictionary<string, object>;
现在你可以看到我正在将返回的ExpandoObject转换为IDictionary。这是ExpandoObject的实现方式,它为您提供属性和值的键值存储。并且每个节点上的所有值都是ExpandoObject类型。
现在在Expando对象的Store集合中找到项目。
List<SingleCardDetails> cardDetails = new List<SingleCardDetails>();
foreach (var item in expando)
{
if (item.Value is ExpandoObject)
{
var store = item.Value as IDictionary<string, object>;
// check properties are on first level
if (!store.Keys.Contains("bizcardData"))
{
cardDetails.Add(TryGetData(store));
}
else // check second level where contact details are under bizcardData
{
foreach (var level2 in item.Value as IDictionary<string, object>)
{
if (level2.Value is ExpandoObject)
{
var storeLevel2 = level2.Value as IDictionary<string, object>;
cardDetails.Add(TryGetData(storeLevel2));
}
}
}
}
}
TryGetData()
方法 -
private static SingleCardDetails TryGetData(IDictionary<string, object> store)
{
object name;
object company;
object designation;
object email;
object phone;
store.TryGetValue("name", out name);
store.TryGetValue("company", out company);
store.TryGetValue("designation", out designation);
store.TryGetValue("email", out email);
store.TryGetValue("phone", out phone);
return new SingleCardDetails
{
Name = Convert.ToString(name),
Company = Convert.ToString(company),
Email = Convert.ToString(email),
Designation = Convert.ToString(designation),
Phone = Convert.ToString(phone)
};
}
这将解析给定的示例并返回SingleCardDetails
的两个对象。
注意:这不是优化代码,有许多方面需要改进。但它应该为您提供如何进行解决方案的指示。
E.g。这可以优化以查找具有递归方法的项目,避免多个循环和条件语句。 优化此项。