使用JSON.NET访问JSON属性以创建C#字典

时间:2011-01-31 07:36:43

标签: c# json json.net

我想将JSON中的字典最终转换为C#字典,而不是很多 我在这里使用JSON.NET库咆哮错误的树吗? JArray类不想给我任何东西来访问属性(只有值),即它告诉我值,但从不告诉我“键”。
我不敢相信没有人会发现这种限制,所以假设我错过了什么。我的混乱尝试是这样的:

鉴于此json:

{
 "appSettings" : [
    {"rows": "5"},
    {"columns" : "7"}
  ]
}

我想把它选成这样的字典:

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);

这是我的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);
}

编辑:感谢@jim,我们离得更近了。 为了完整起见,我将记录我需要的稍微尴尬的步骤,以获得我需要的对象:

我不得不改变我的JSON。 我没有使用数组(如上面的代码中那样),而是使用了更简单/更真实的字典:

var json = @"
{ 
  ""appSettings"" : { 
    ""ViewRows""    : ""1"",
    ""ViewColumns"" : ""2""
    }
}";

然后我必须解析,获取JSON JObject ,然后转换回字符串,然后反序列化

var jo = JObject.Parse(jsonText);
var appSettings = jo["appSettings"];
var appSettings = JsonConvert.DeserializeObject<Dictionary<string, string>>(appSettings.ToString());

因此,我的问题的一部分是让JSON感到困惑。 即便如此,如果有一种更优雅的方式来做到这一点,我全都听见了。

EDIT2 :我仍然需要解决上面的原始问题,将JSON数组转换为字典。一旦我的JSON被更正为包含正确的名称/值对:

"connectionStrings": [
{"name" : "string1", "value" : "value1"},
{"name" : "string2", "value" :"value2"},
]

这是解决它的代码(它看起来很像我原来的尝试):

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);

这只有在没有其他数组的情况下才有效。

4 个答案:

答案 0 :(得分:11)

熊猫,

从詹姆斯·纽顿国王那里逐字逐句地提出类似的问题:

// Json.NET does this...

string json = @"{""key1"":""value1"",""key2"":""value2""}";
Dictionary<string, string> values 
    = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

你可以在这里找到主题:

How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?

希望这会有所帮助(不是100%确定它如何与复杂的树结构一起使用)

答案 1 :(得分:2)

这是实现此目的的MS方式,但它非常复杂,我认为比YvesR的解决方案更容易实现。

http://atsung.wordpress.com/2008/08/07/javascriptserializer-example/

答案 2 :(得分:1)

要将js assosiative数组转换为字典,请使用如下转换器:

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();
        }
    }
}

然后用法如下:

Dictionary<string, string> dictionary;
dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(value, new AssosiativeArrayConverter);

其中T是你的词典,例如字典或任何你喜欢的。

在我的案例中反序列化的Json如下所示:

  

{      “MyDictionary”:{          “key1”:[              “VALUE1”              “值2”,              “值3”          ]          “key2”:[]   }

答案 3 :(得分:0)

我知道这不是一个直接解决你问题的正确答案,但对于C#中的所有JSON内容,这里是一个非常好的库的链接,你可以使用它来轻松地用C#中的JSON做任何事情。

http://james.newtonking.com/pages/json-net.aspx