将JSON字符串解析为List
string json = "{\"People\":[{\"FirstName\":\"Hans\",\"LastName\":\"Olo\"} {\"FirstName\":\"Jimmy\",\"LastName\":\"Crackedcorn\"}]}"; var obj = JObject.Parse(json); List first; List last; foreach (var child in obj["People"].Children()) { var name = child.First()["countryName"].ToString(); var two = child.First()["countryCode"].ToString(); var three = child.First()["isoAlpha3"].ToString(); countries.Add(name); twoCharCodes.Add(two); threeCharCodes.Add(three); Console.Write("Name:\t\t{0}\n2CharCode:\t{1}\n3CharCode:\t{2}\n\n", name, two, three); }
我正在寻找一种方法将每个FirstName值添加到第一个List中,并将LastName值与最后一个List相同。 这样做的最佳方法是什么?
上面的代码打破了:
var name = child.First()["countryName"].ToString();
有这个错误:
Cannot access child value on Newtonsoft.Json.Linq.JProperty
任何建议?
似乎是一种不好的方式(创建两个相关的列表),但我假设你有你的理由。
我将JSON字符串(在您的示例中有一个拼写错误,它缺少两个对象之间的逗号)解析为强类型对象,然后使用几个LINQ查询来获取这两个列表。
void Main() { string json = "{\"People\":[{\"FirstName\":\"Hans\",\"LastName\":\"Olo\"},{\"FirstName\":\"Jimmy\",\"LastName\":\"Crackedcorn\"}]}"; var result = JsonConvert.DeserializeObject(json); var firstNames = result.People.Select (p => p.FirstName).ToList(); var lastNames = result.People.Select (p => p.LastName).ToList(); } public class Person { public string FirstName { get; set; } public string LastName { get; set; } } public class RootObject { public List People { get; set; } }
由于您使用的是JSON.NET,我个人会使用序列化,以便您可以对对象进行Intellisense支持。 您将需要一个代表您的JSON结构的类。 您可以手动构建它,或者您可以使用类似json2csharp的东西为您生成它:
例如
public class Person { public string FirstName { get; set; } public string LastName { get; set; } } public class RootObject { public List People { get; set; } }
然后,您可以简单地调用JsonConvert
的方法将JSON反序列化为对象:
RootObject instance = JsonConvert.Deserialize(json);
然后你有Intellisense:
var firstName = instance.People[0].FirstName; var lastName = instance.People[0].LastName;
我在我的项目中使用这个JSON Helper类。 我在一年前在网上找到它但丢失了源URL。 所以我直接从我的项目中粘贴它:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Runtime.Serialization.Json; using System.IO; using System.Text; /// /// JSON Serialization and Deserialization Assistant Class /// public class JsonHelper { /// /// JSON Serialization /// public static string JsonSerializer (T t) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(); ser.WriteObject(ms, t); string jsonString = Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); return jsonString; } /// /// JSON Deserialization /// public static T JsonDeserialize (string jsonString) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); T obj = (T)ser.ReadObject(ms); return obj; } }
您可以像这样使用它:按照Craig W.的建议创建类。
然后像这样反序列化
RootObject root = JSONHelper.JsonDeserialize(json);
希望将此作为评论发布作为接受答案的附注,但这有点不清楚。 纯粹作为旁注:
如果您不需要对象本身,并且您希望项目中没有其他未使用的类,则可以使用以下内容进行解析:
var list = JObject.Parse(json)["People"].Select(el => new { FirstName = (string)el["FirstName"], LastName = (string)el["LastName"] }).ToList(); var firstNames = list.Select(p => p.FirstName).ToList(); var lastNames = list.Select(p => p.LastName).ToList();
即使使用强类型人类,您仍然可以通过使用JObject.Parse(json)["People"].ToObject
创建列表来跳过根对象>()
JObject.Parse(json)["People"].ToObject
当然,如果您确实需要重用对象,最好从一开始就创建它们。 只是想指出替代方案;) >()