string json = "{\"People\":[{\"FirstName\":\"Hans\",\"LastName\":\"Olo\"}
{\"FirstName\":\"Jimmy\",\"LastName\":\"Crackedcorn\"}]}";
var obj = JObject.Parse(json);
List<string> first;
List<string> 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
有什么建议吗?
答案 0 :(得分:12)
似乎是一种糟糕的方式(创建两个相关的列表)但我假设你有理由。
我将JSON字符串(在您的示例中有一个拼写错误,它在两个对象之间缺少逗号)解析为强类型对象,然后使用几个LINQ查询来获取这两个列表。
void Main()
{
string json = "{\"People\":[{\"FirstName\":\"Hans\",\"LastName\":\"Olo\"},{\"FirstName\":\"Jimmy\",\"LastName\":\"Crackedcorn\"}]}";
var result = JsonConvert.DeserializeObject<RootObject>(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<Person> People { get; set; }
}
答案 1 :(得分:7)
由于您使用的是JSON.NET,我个人会选择序列化,以便您可以为对象提供Intellisense支持。您需要一个代表您的JSON结构的类。您可以手动构建它,也可以使用json2csharp之类的东西为您生成它:
e.g。
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class RootObject
{
public List<Person> People { get; set; }
}
然后,您只需调用JsonConvert
的方法将JSON反序列化为对象:
RootObject instance = JsonConvert.Deserialize<RootObject>(json);
然后你有Intellisense:
var firstName = instance.People[0].FirstName;
var lastName = instance.People[0].LastName;
答案 2 :(得分:0)
我在我的项目中使用这个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;
/// <summary>
/// JSON Serialization and Deserialization Assistant Class
/// </summary>
public class JsonHelper
{
/// <summary>
/// JSON Serialization
/// </summary>
public static string JsonSerializer<T> (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;
}
/// <summary>
/// JSON Deserialization
/// </summary>
public static T JsonDeserialize<T> (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<RootObject>(json);
答案 3 :(得分:0)
希望将此作为评论发布作为接受答案的附注,但这有点不清楚。 纯粹作为旁注:
如果您不需要对象本身并且希望项目中没有其他未使用的类,则可以使用以下内容进行解析:
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<List<Person>>()
列表来跳过根对象
当然,如果您确实需要重用对象,那么从一开始就创建它们会更好。只是想指出替代方案;)
答案 4 :(得分:0)
尝试一下:
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List<Man> Men = new List<Man>();
Man m1 = new Man();
m1.Number = "+1-9169168158";
m1.Message = "Hello Bob from 1";
m1.UniqueCode = "0123";
m1.State = 0;
Man m2 = new Man();
m2.Number = "+1-9296146182";
m2.Message = "Hello Bob from 2";
m2.UniqueCode = "0125";
m2.State = 0;
Men.AddRange(new Man[] { m1, m2 });
string result = JsonConvert.SerializeObject(Men);
Console.WriteLine(result);
List<Man> NewMen = JsonConvert.DeserializeObject<List<Man>>(result);
foreach(Man m in NewMen) Console.WriteLine(m.Message);
}
}
public class Man
{
public string Number{get;set;}
public string Message {get;set;}
public string UniqueCode {get;set;}
public int State {get;set;}
}