【问题标题】:Using JSON.NET to access JSON attributes to create a C# dictionary使用 JSON.NET 访问 JSON 属性以创建 C# 字典
【发布时间】:2011-01-31 07:36:42
【问题描述】:

我想毫不费力地将 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);

这是我的单元测试:

[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"},
]

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

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

这只有在你没有其他数组时才有效。

【问题讨论】:

    标签: c# json json.net


    【解决方案1】:

    熊猫,

    詹姆斯·牛顿·金本人对类似问题的逐字逐句:

    // 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% 确定这如何处理复杂的树结构)

    【讨论】:

    • 大卫,我知道 :-),因此我对那个图书馆有更多的信息。实际上,我纯粹基于此引用了附加答案,否则,将“完成其他峰会”-不用担心(眨眼图标)
    【解决方案2】:

    这是执行此操作的 MS 方法,但它非常复杂,我真的认为比 YvesR 的解决方案可能更容易实现。

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

    【讨论】:

    • YvesR - 不是我 :-}。我认为这也是一个糟糕的投票。我讨厌这种情况发生并且没有评论! - 没有意义
    【解决方案3】:

    要将js关联数组转换成字典,可以使用转换器,如下:

    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 如下所示:

    { “我的字典”:{ “key1”:[ “价值1”, “价值2”, “价值3” ], “key2”:[] }

    【讨论】:

    • 嘿,不错的方法 +1
    【解决方案4】:

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

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

    【讨论】:

    • 我实际上在我的问题中使用 JSON.NET 库。这是问题的一部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 2011-03-03
    相关资源
    最近更新 更多