从IEnumerable foreach循环中获取值

本文关键字:获取 循环 IEnumerable foreach | 更新日期: 2023-09-27 17:59:54

我需要从JSON文件创建一个c#对象,并且必须使用以下工作解决方案:

JSON:

{
"AK": {
    "Anchorage": [{
        "Name": "John Doe",
        "Address": "123 Main St.",
        "City": "Anchorage",
        "State": "AK",
        "Zip": "12345"
    }],
    "Fairbanks": [{
        "Name": "Sally Smith",
        "Address": "987 Main St.",
        "City": "Fairbanks",
        "State": "AK",
        "Zip": "98765"
    }]
}
}

代码:

public class Location
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}
// ------------------------------------------------------------------
string json = File.ReadAllText(@"C:json.txt");
dynamic deserialisedJson = JsonConvert.DeserializeObject(json);
var locations = new List<Location>();
foreach (var root in deserialisedJson)
{
    foreach (var state in root)
    {
        foreach (var city in state)
        {
            foreach (var location in city)
            {
                Location loc = new Location();
                loc.Name = location.First["Name"];
                loc.Address = location.First["Address"];
                loc.City = location.First["City"];
                loc.State = location.First["State"];
                loc.Zip = location.First["Zip"];
                locations.Add(loc);
            }
        }
    }
} 

但我需要将以上内容合并到SSIS包中,该包只允许.NET 3.5及更低版本。下面的代码行需要.NET 4.0及以上版本:

dynamic deserialisedJson = JsonConvert.DeserializeObject(json);

我试图通过使用IEnumerable来解决这个限制,但我不确定如何获取我需要的值的语法?

string json = File.ReadAllText(@"C:json.txt");
var deserialisedJson = (IEnumerable)JsonConvert.DeserializeObject(json);
var locations = new List<Location>();
foreach (var root in deserialisedJson)
{
    foreach (var state in (IEnumerable)root)
    {
        foreach (var city in (IEnumerable)state)
        {
            foreach (var location in (IEnumerable)city)
            {
                Location loc = new Location();
                loc.Name = //What goes here???
                loc.Address = //What goes here???
                loc.City = //What goes here???
                loc.State = //What goes here???
                loc.Zip = //What goes here???
                locations.Add(loc);
            }
        }
    }
}

从IEnumerable foreach循环中获取值

这使用Linq到JSON来选择您想要的所有Location对象:

var deserialisedJson = (IEnumerable)JsonConvert.DeserializeObject(json);
JObject jObj = JObject.Parse(json);
//Get all tokens that are under AK/(some descendant)/all items from collection
var result = jObj.SelectTokens("AK.*.[*]")
                    .Select(x => new Location
                    {
                        Name = x["Name"].Value<string>(),
                        Address = x["Address"].Value<string>(),
                        City = x["City"].Value<string>(),
                        State = x["State"].Value<string>(),
                        Zip = x["Zip"].Value<string>(),
                    }).ToList();

经过测试,这适用于.Net 3.5项目,该项目具有适用于.Net

Newtonsoft.Json

这里有一个快速解决方案:

var deserialized = JsonConvert.DeserializeObject<JObject>(json);
var locations = (
    from state in deserialized.Properties().Select(v => v.Value).OfType<JObject>()
    from city in state.Properties().Select(v => v.Value).OfType<JArray>()
    from location in city
    select new Location
    {
        Name = location.Value<string>("Name"),
        Address = location.Value<string>("Address"),
        City = location.Value<string>("City"),
        State = location.Value<string>("State"),
        Zip = location.Value<string>("Zip")
    }).ToList();

您可以使用类来让newtonsoft解决您需要的

public class Location
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}
public class AK
{
    public Location[] Anchorage { get; set; }
    public Location[] Fairbanks { get; set; }
}   

var ak = JsonConvert.DeserializeObject<AK>(json);