反序列化值始终返回null - RestSharp获取请求

时间:2015-09-01 15:44:40

标签: c# json dictionary deserialization restsharp

这是我的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。上面的代码有什么问题。我假设迭代有问题。请建议代码来解决这个问题。 谢谢!

1 个答案:

答案 0 :(得分:1)

为了将数据反序列化为强类型对象,对象层次结构应该正确匹配。但是给定的JSON示例看起来就像在根元素下使用一些编码对象一样生成。我认为您可以使用动态反序列化来获取嵌套对象,而无需创建不必要的类型以解析JSON。

为了给你解决或快速指导。我将json.netExpandoObject一起使用。

我只是使用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。这可以优化以查找具有递归方法的项目,避免多个循环和条件语句。 优化此项