7

I'm trying to deserialize JSON in this format:

{
   "data": [
      {
         "installed": 1,
         "user_likes": 1,
         "user_education_history": 1,
         "friends_education_history": 1,
         "bookmarked": 1
      }
   ]
}

to a simple string array like this:

{
    "installed",
    "user_likes",
    "user_education_history",
    "friends_education_history",
    "bookmarked"
}

using JSON.NET 4.0

I've gotten it to work using the `CustomCreationConverter'

public class ListConverter : CustomCreationConverter<List<string>>
{
public override List<string> Create(Type objectType)
{
    return new List<string>();
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    var lst = new List<string>();

    //don't care about the inital 'data' element
    reader.Read();

    while (reader.Read())
    {
        if (reader.TokenType == JsonToken.PropertyName)
        {
            lst.Add(reader.Value.ToString());
        }
    }
    return lst;
}
}

but this really seems like overkill, especially if I want to create one for many different json responses.

I've tried using JObject but it doesn't seem like I'm doing it right:

List<string> lst = new List<string>();
JObject j = JObject.Parse(json_string);
foreach (JProperty p in j.SelectToken("data").Children().Children())
{
    lst.Add(p.Name);
}

Is there a better way to do this?

2 Answers 2

7

There are many ways you can do that, and what you have is fine. A few other alternatives are shown below:

  • Get the first element of the array, instead of all the children
  • Use SelectToken to go to the first array element with a single call

        string json = @"{
          ""data"": [
            {
              ""installed"": 1,
              ""user_likes"": 1,
              ""user_education_history"": 1,
              ""friends_education_history"": 1,
              ""bookmarked"": 1
            }
          ]
        }";
    
        JObject j = JObject.Parse(json);
    
        // Directly traversing the graph
        var lst = j["data"][0].Select(jp => ((JProperty)jp).Name).ToList();
        Console.WriteLine(string.Join("--", lst));
    
        // Using SelectToken
        lst = j.SelectToken("data[0]").Children<JProperty>().Select(p => p.Name).ToList();
        Console.WriteLine(string.Join("--", lst));
    
Sign up to request clarification or add additional context in comments.

2 Comments

Is there any difference between those 2 ways in performance or anything?
If any, I think will probably be negligible. But as always, try in your scenario, measure it, and decide for yourself.
1

You can use this solution as well to get the key and value:

string key, value;
var propertyList = (JObject)j["data"];
foreach (var property in propertyList)
{
   key = property.Key;
   value = property.Value.ToString();
} 

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.