2

I have the following JSon string returned from a service:

{
    "links": {
        "data": {
            "self": {
                "body": "",
                "content_type": "",
                "href": "",
                "method": "GET",
                "name": ""
            }
        }
    },
    "results": [{
        "data": {
            "categories": {
                "41370_10": "abc",
                "41370_11": "abc",
                "41370_2": "abc",
                "41370_5": "abc"
            }
        },
        "metadata": {
            "categories": {
                "41370": {
                    "key": "41370",
                    "name": "123"
                },
                "41370_10": {
                    "bulk_shared": false,
                    "key": "41370_10",
                    "name": "some name"
                },
                "41370_11": {
                    "allow_undefined": false,
                    "key": "41370_11",
                    "name": "some name 2"
                },
                "41370_2": {
                    "key": "41370_2",
                    "key_value_pairs": false,
                    "name": "some name 3"
                }
            }
        }
    },
    {
        "data": {
            "categories": {
                "72051_2": "asd",
                "72051_3": "asd"
            }
        },
        "metadata": {
            "categories": {
                "72051": {
                    "key": "72051",
                    "name": "some name 4"
                },
                "72051_2": {
                    "key": "72051_2",
                    "name": "some name 5"
                }
            }
        }
    },
    {
        "data": {
            "categories": {
                "112644_2": "zxc"
            }
        },
        "metadata": {
            "categories": {
                "112644": {
                    "key": "112644",
                    "name": "some name 6"
                },
                "112644_2": {
                    "hidden": false,
                    "key": "112644_2",
                    "name": "some name 7"
                }
            }
        }
    }]
}

How do I process this data to get a nice, plain Dictionary? It would look something like this:

{"some name", "abc"}, 
{"some name 2", "abc"}, 
{"some name 3", "abc"},
{"some name 5", "asd"},
{"some name 6", "zxc"}

Currently trying to use c#, json.net, with scarce success. Any help greatly appreciated.

Update 1: I've gotten as far as getting the JTokens out of it, but am not sure how to separate the data from metadata (yes, I realize how absurd that sounds).

//get json object
JObject cjob = JObject.Parse(response.Content.ReadAsStringAsync().Result);

IEnumerable<JToken> categorymetadata = cjob.Descendants()
    .Where(t => t.Type == JTokenType.Property && ((JProperty)t).Name == "categories")
    .SelectMany(p => ((JProperty)p).Value);
3
  • process this data == deserialize Commented Oct 4, 2018 at 21:10
  • 1
    You need a JSON parser look at JSON.NET Lib. If you have tried the same library (or not), then post the code of what you have so far for us to help. Commented Oct 4, 2018 at 21:25
  • Ok. My current attempt posted. Commented Oct 4, 2018 at 21:47

3 Answers 3

2

The following LINQ-to-JSON query should give you the result you are looking for:

Dictionary<string, string> dict = cjob["results"]
    .Children<JObject>()
    .Select(result => result.SelectToken("metadata.categories").Children<JProperty>()
                            .Join(result.SelectToken("data.categories").Children<JProperty>(),
                                  metaCat => metaCat.Name,
                                  dataCat => dataCat.Name,
                                  (metaCat, dataCat) => new
                                  {
                                      Name = (string)metaCat.Value["name"],
                                      Value = (string)dataCat.Value
                                  }
                            )
    )
    .SelectMany(a => a)
    .ToDictionary(a => a.Name, a => a.Value);

foreach (var kvp in dict)
{
    Console.WriteLine(kvp.Key + ": " + kvp.Value);
}

This does an inner join between the categories in the metadata object and those in the data object for each result and selects the joined properties into a list (IEnumerable really) of anonymous name-value pairs. The lists of pairs are then flattened down to a single list and finally placed into a dictionary.

I am making the following assumptions about your data:

  • each result object will always have both metadata and data
  • the category names and data values will always be strings
  • the category names will be unique across all results

If these assumptions don't hold you will run into errors and will need to make adjustments to the code.

Here is a working demo: https://dotnetfiddle.net/WkztV5

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

Comments

1

I would recommend using the JsonConvert.DeserializeObject you can Deserialize your json into objects and then do what ever you want with those object for example:

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}

string json = @"{
'Email': '[email protected]',
'Active': true,
'CreatedDate': '2013-01-20T00:00:00Z',
'Roles': [
'User',
'Admin']
}";

Account account = JsonConvert.DeserializeObject<Account>(json);

Console.WriteLine(account.Email);
// [email protected]

https://www.newtonsoft.com/json/help/html/DeserializeObject.html

If you want to convert your json into objects without figuring it out: http://json2csharp.com/ is a really nifty tool just copy and past your json into there.

In your case you will have a root object like this:

public class RootObject
{
    public Links links { get; set; }
    public List<Result> results { get; set; }
}

and you can just look through your results to get what you want.

Comments

0

I think it's easy to do it like this, but I only had a couple levels in the JSON heirarchy

dynamic deserialized = JsonConvert.DeserializeObject((string)data);
newObj = deserialized["objName"].value == null ? "" : deserialized["objName"].value;

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.