I want to convert what is ultimately a dictionary in JSON to a C# dictionary without much ado.
Am I barking up the wrong tree by using the JSON.NET library here? The JArray class doesn't want to give me anything to access the attribute (only the value) ie it tells me the value but never the "key".
I can't quite believe no one else would find this limiting, so am assuming I'm missing something. My muddled attempt is this:
Given this json:
{
"appSettings" : [
{"rows": "5"},
{"columns" : "7"}
]
}
I would like to select this into a dictionary like this:
var dict = jsonObject["appSettings"].Select(s => new
{
key = s.Name, // wish this property existed
value = s.Value // wish this property existed
}).ToDictionary(s => s.key, s => s.value);
This is my UnitTest:
[Test]
public void CanLoadJsonAppSettings()
{
var json = @"
""{appSettings"" : [
{""ViewRows"" : ""1""},
{""ViewColumns"" : ""2""}
]}";
var dict = CreateJsonDictionary(json);
Assert.That(dict.Count, Is.EqualTo(2));
}
public CreateJsonDictionary(string jsonText)
{
var jsonObject = JObject.Parse(jsonText);
return jsonObject["appSettings"].Select(s => new
{
key = s.Name,
value = s.Value
}).ToDictionary(s => s.key, s => s.value);
}
EDIT: Thanks to @jim, we are a little closer. For completeness, I will document the slightly awkward step I needed in order to get at the object I needed:
I had to change my JSON. Instead of using an array (as in the code above) I used a more simple/truer dictionary:
var json = @"
{
""appSettings"" : {
""ViewRows"" : ""1"",
""ViewColumns"" : ""2""
}
}";
Then I had to Parse, get a JSON JObject, then convert back to a string, and then Deserialize:
var jo = JObject.Parse(jsonText);
var appSettings = jo["appSettings"];
var appSettings = JsonConvert.DeserializeObject<Dictionary<string, string>>(appSettings.ToString());
So part of my problem, was getting JSON confused. Even so, if there is a more elegant way to do this, I'm all ears.
EDIT2: I still had to solve the original problem above, converting a JSON array to a dictionary. Once my JSON is corrected to contain proper name/value pairs:
"connectionStrings": [
{"name" : "string1", "value" : "value1"},
{"name" : "string2", "value" :"value2"},
]
This is the code that solved it (nb it looks a lot like my original attempt):
var jsonObj = JObject.Parse(jsonText);
var conStrings = jsonObj.Properties().Select(s =>
new {
key = s.Name,
value = s.Value.ToString()
}).ToDictionary(s => s.key, s => s.value);
And this only works if you have no other arrays.