Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a JSON.NET JObject's Properties/Tokens into Dictionary Keys

Tags:

I'm using JSON.NET to parse a JSON reponse from openexhangerates.org server side using .NET. The response contains a nested object ("rates") which has a long list of numeric properties:

    {     "disclaimer": "Exchange rates provided for informational purposes only, with no guarantee whatsoever of accuracy, validity, availability, or fitness for any purpose; use at your own risk. Other than that, have fun! Usage subject to acceptance of terms: http://openexchangerates.org/terms/",     "license": "Data sourced from various providers with public-facing APIs; copyright may apply; not for resale; no warranties given. Usage subject to acceptance of license agreement: http://openexchangerates.org/license/",         "timestamp": 1357268408,         "base": "USD",         "rates": {             "AED": 3.673033,             "AFN": 51.5663,             "ALL": 106.813749,             "AMD": 403.579996,             etc...         }     } 

The property names correspond to the currency type (e.g. "USD"). I need to assume that the list of properties can change over time, so I want to convert the object into a Dictionary instead of a corresponding C# object.

So instead of deserializing the JSON object into something like this:

class Rates { public decimal AED; // United Arab Emirates Dirham public decimal AFN; // Afghan Afghani public decimal ALL; // Albanian Lek public decimal AMD; // Armenian Dram // etc... } 

I want to end up with this:

Dictionary<string,decimal>() {{"AED",0.2828},{"AFN",0.3373},{"ALL",2.2823},{"AMD",33.378} // etc...}; 

How do I do this starting from either the response string or from the JObject produced by calling JObject.Parse(responseString)?

like image 293
Emmanuel Avatar asked Jan 04 '13 17:01

Emmanuel


People also ask

How do I get keys for JObject?

You can simply convert the JObject into a Dictionary object and access the method Keys() from the Dictionary object.

How can I get JToken key?

You can use the Children<T>() method to get a filtered list of a JToken's children that are of a certain type, for example JObject . Each JObject has a collection of JProperty objects, which can be accessed via the Properties() method. For each JProperty , you can get its Name .

How do you serialize a dictionary to a JSON string?

you can use the json. dumps(dict) to convert the dictionary to string.

What is JObject and JToken?

The JToken hierarchy looks like this: JToken - abstract base class JContainer - abstract base class of JTokens that can contain other JTokens JArray - represents a JSON array (contains an ordered list of JTokens) JObject - represents a JSON object (contains a collection of JProperties) JProperty - represents a JSON ...


1 Answers

JObject already implements IDictionary<string, JToken>, so I suspect that when you've navigated down to the rates member, you should be able to use:

var result = rates.ToDictionary(pair => pair.Key, pair => (decimal) pair.Value); 

Unfortunately it uses explicit interface implementation, which makes this a bit of a pain - but if you go via the IDictionary<string, JToken> interface, it's fine.

Here's a short but complete example which appears to work with the JSON you've provided (saved into a test.json file):

using System; using System.Collections.Generic; using System.IO; using System.Linq; using Newtonsoft.Json.Linq;  class Test {     static void Main()     {         JObject parsed = JObject.Parse(File.ReadAllText("test.json"));         IDictionary<string, JToken> rates = (JObject) parsed["rates"];         // Explicit typing just for "proof" here         Dictionary<string, decimal> dictionary =             rates.ToDictionary(pair => pair.Key,                                pair => (decimal) pair.Value);         Console.WriteLine(dictionary["ALL"]);     } } 
like image 119
Jon Skeet Avatar answered Oct 12 '22 17:10

Jon Skeet