反序列化值总是 return null - RestSharp Get 请求

Deserialized Values always return null - RestSharp Get request

这是我的 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;
         }

但是这里的名称、公司等所有值都是空的。上面的代码有什么问题。我假设迭代有问题。请建议代码来解决这个问题。 谢谢!

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

为了给您解决方案或快速指导。我要使用 json.net with ExpandoObject

我将简单地使用 JObject 方法来解析问题中给出的 sample json。在实际场景中,如果您拥有此类对象的数组,则可以使用 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)
                        };
        }

这将解析给定的样本和 returns 两个 SingleCardDetails 的对象。

注意:这不是优化代码,有许多地方需要改进。但它应该为您提供如何继续解决问题的指导。

例如这可以优化为使用递归方法查找项目,避免多个循环和条件语句。 尽可能优化它