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 js开发者_JAVA技巧on = @"
{
""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.
Panda,
Verbatim from james newton king himself on SO to a similar question:
// Json.NET does this...
string json = @"{""key1"":""value1"",""key2"":""value2""}";
Dictionary<string, string> values
= JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
you can find the thread here:
How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?
hope this helps (tho not 100% certain on how this works with complex tree structures)
This is the MS way to do this, but it's quite complex and I really think than YvesR's solution might be easier to implement.
http://atsung.wordpress.com/2008/08/07/javascriptserializer-example/
To convert js assosiative array into dictionary, use may use converter which is as follows:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace MyJsonConverters
{
public class AssosiativeArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.GetInterface(typeof(IDictionary<,>).Name) != null;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
var result = Activator.CreateInstance(objectType);
var addMethod = result.GetType().GetMethod("Add");
var dictionaryTypes = objectType.GetGenericArguments();
foreach (JProperty property in jObject.Properties())
{
var key = Convert.ChangeType(property.Name, dictionaryTypes[0]);
var value = serializer.Deserialize(property.Value.CreateReader(), dictionaryTypes[1]);
addMethod.Invoke(result, new[] { key, value });
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
then usage is as follows:
Dictionary<string, string> dictionary;
dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(value, new AssosiativeArrayConverter);
where T is your Dictionary e.g. Dictionary or whatever you like.
Json which is deserialized in my case looks like follows:
{ "MyDictionary": { "key1": [ "value1", "value2", "value3" ], "key2": [ ] }
I know it is not a proper answer direct to your question, but for all JSON stuff in C# here is the link for the a very good library you can use to easy do anything with JSON in C#.
http://james.newtonking.com/pages/json-net.aspx
精彩评论