1

This is my JSON response :

    {
      "-JxpUA1eC_I3miJrdGGs": {
        "company": "Microsoft",
        "designation": "Chief Executive officer",
        "email": "[email protected]",
        "name": "Nathan White",
        "phone": "51342212333"
      },
      "-Jy5dki5KkgyxQBuDwNI": {
        "bizcardData": {
          "company": "Spotify",
          "designation": "Designer",
          "email": "[email protected]",
          "name": "Phani Komaravolu",
          "phone": "5135921240"
        },
        "transData": {
          "date": "15-08-31",
          "location": "39.1395996,-84.5295417",
          "tag": "sender",
          "time": "22:05:38"
        }}
     }

I am deserializing it using RestSharp as :

var resultList = SimpleJson.DeserializeObject<Dictionary<string, SingleCardDetails>>(content);

Here is my SingleCardDetails Object :

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; }
    }

I am trying to use that to iterate over using :

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;
         }

But all the values here like name, company, etc., are null. What is wrong with the above code. I am assuming that there is something wrong with the iteration. Please suggest code to solve this. Thanks!

8
  • Fix your json. where you put the } changes your model... Commented Sep 1, 2015 at 15:59
  • Have you checked what you are getting in content? as @Eser said if you fix your JSON it will have different object hierarchy. Commented Sep 1, 2015 at 16:05
  • { "-JxpTAV-_NksLh_EKBFV": { "company": "Amazon", "designation": "Designer", "email": "[email protected]", "name": "Mike", "phone": "5135921240" }, "-JxpTNmQ_uEQ9r2q-Mo6": { "company": "Ford", "designation": "Developer", "email": "[email protected]", "name": "Gilfoyle", "phone": "51342212333" } } } Commented Sep 1, 2015 at 16:08
  • This is my actual json. Sorry I missed braces in the question. Commented Sep 1, 2015 at 16:11
  • I can print my content and it is working fine. I think there is a problem with getting values from the deserialized object or something wrong with declaring the SimpleJson.DeserializeContent part Commented Sep 1, 2015 at 16:14

1 Answer 1

1

In order to get the data deserialized into strongly typed objects the object hierarcy should match properly. But the given sample of JSON looks like generated on the fly with some encoded objects under root element. I think you can use the Dynamic deserialization to get the nested objects with out creating un-necessary types in order to parse JSON.

In order to give you resolution or a quick guidance. I'm going to use the json.net with ExpandoObject.

I'll simply be using the JObject method to parse the sample json given in the question. In real scneario if you have Array of such object than you could use JArray. The JObject parse any string json provided to JObject. But JObject can not be directly casted into ExpandoObject so I'm using a quick fix for that from the source here. Below is the method that will do the needful to convert JObject to 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");
        }
    }

Now to parse your JSON first simpley call the parser on provided JSON.

 dynamic result = JObject.Parse(JsonDataTest.SampleJson);
 var expando = ConvertJTokenToObject(result) as IDictionary<string, object>;

Now as you can see I'm casting the returned ExpandoObject to IDictionary. This is how the ExpandoObject is implemented it give you a key value store for properties and values. And all the values on each node is of type ExpandoObject.

Now find the items in the Store collection of Expando object.

 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() method -

 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)
                        };
        }

This will parse the given sample and returns two objects of SingleCardDetails.

Note:This is not optimized code and have many areas to improve. But it should give you the directions how to proceed towards the solution.

E.g. This can be optimized to find items with recursive approach avoiding multiple loops and conditional statements. Optimize this as you may.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.