【问题标题】:Getting value from nested Dictionary从嵌套字典中获取价值
【发布时间】:2016-08-24 12:47:08
【问题描述】:

我有以下反序列化 JSON 文件的代码,然后我需要遍历字典以获取最里面的值并分配给 c# 对象:

public class Location
{
   public string Id { get; set; }
   public string Name { get; set; }
   public string Street { get; set; }
   public string City { get; set; }
   public string State { get; set; }
   public string Zip { get; set; }
}

string json = File.ReadAllText(@"C:\file.json");
JavaScriptSerializer ser = new JavaScriptSerializer();
var dict = ser.Deserialize<Dictionary<string, object>>(json);

foreach (var outer in dict)
{
    foreach (var middle in (Dictionary<string, object>)outer.Value)
    {
        foreach (var inner in (ArrayList)middle.Value)
        {
            foreach (var loc in (Dictionary<string, object>)inner)
            {
                var location = new Location();
                location.Id = ??;
                location.Name = ??;
                location.Street = ??;//...etc
            }
         }
    }
}

当我调试并单步执行代码时,最内层循环的值显示:

loc {[ID, 601391]}  System.Collections.Generic.KeyValuePair<string,object>
    Key "ID"    string
    Value"601391"   object {string}

如何获取ID 的值并将其分配给location.Id

【问题讨论】:

  • 你为什么要反序列化成字典而不是直接反序列化成你的对象???
  • @mituw16 他可能无法控制数据源
  • @JamesRalston 您不必控制数据源来构建与源匹配的对象然后反序列化到该对象
  • @mituw16 是的,我想我可以更广泛地假设这种方法可能有其他原因。虽然它看起来确实是一个奇怪的结构

标签: c# json dictionary


【解决方案1】:

使用内部字典中包含的KeyValuePairs的KeyValue

// outer loop
// middle loop
var location = new Location();
foreach (var loc in (Dictionary<string, object>)inner) {
    if (loc.Key == "ID") {
        location.Id = loc.Value.ToString();
        continue;
    }
    // if (loc.Key == "Name") ...
}

或使用索引器访问某些命名值(可能比遍历所有条目更快)。

// outer loop
// middle loop
var innerDict = (Dictionary<string, object>)inner;
var location = new Location();
if (innerDict.ContainsKey("ID")) {
    location.Id = innerDict["ID"];
}

【讨论】:

  • 为每个属性设置条件会很乏味,但没有用处
  • 你说得对,我添加了另一个直接访问所需密钥的解决方案。
  • 似乎仍然需要检查每个属性
【解决方案2】:

您只需要像这样转换值并使用反射使代码更具可读性

var props = typeof(Location).GetProperties();

string json = File.ReadAllText(@"C:\file.json");
JavaScriptSerializer ser = new JavaScriptSerializer();
var dict = ser.Deserialize<Dictionary<string, object>>(json);

foreach (var outer in dict)
{
    foreach (var middle in (Dictionary<string, object>)outer.Value)
    {
        foreach (var inner in (ArrayList)middle.Value)
        {
            foreach (var loc in (Dictionary<string, object>)inner)
            {
                var location = new Location();
                var prop = props.FirstOrDefault(p => p.Name.ToUpper() == loc.Key.ToUpper());

                if (prop != null)
                {
                    prop.SetValue(location, loc.Value);
                }


            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    • 2022-10-07
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多