如何使用 Newtonsoft.Json 从 JSON 子数组中获取数据?
How to get data from JSON sub array using Newtonsoft.Json?
我更新了 JSON table,如下所示
{ "Students" : [ {"name": "Alex", "lastname": "Dean", "Properties" : [{"iq":120, "hair": "black", "glasses": "yes", "Grades": [{"Math": 44, "Lit": "88"}]}, {"iq":120, "hair": "blond", "glasses": "yes", "Grades" : [{"Math": 22, "Lit": "81"}]}, {"iq":144, "hair": "brown", "glasses": "yes", "Grades": [{"Math": 44, "Lit": "88"}]}, {"iq":120, "hair": "red", "glasses": "yes", "Grades" : [{"Math": 44, "Lit": "88"}]}]}]}
我设法获取了不在子数组中的名字和姓氏,但无法弄清楚如何获取子数组中的其他数据。在数组 "Students" 中有一个名为 "Properties" 的子数组,在 "Properties" 中有另一个名为 "Grades".
的子数组
如何获得 "hair" 和 "math" 属性?
这是我获取名字和姓氏的方法。
这是我的网络服务class
public class WebService
{
public WebService ()
{
}
public async Task<Rootobject> GetStudentInfoAsync (string apiurl) {
var client = new HttpClient ();
var response = await client.GetStringAsync(string.Format(apiurl));
return JsonConvert.DeserializeObject<Rootobject>(response.ToString());
}
}
这是我想出的视图模型。为什么它不起作用。我没有得到值。
namespace MyApp
{
public class Grade
{
public string Math { get; set; }
public string Lit { get; set; }
}
public class Property
{
public int iq { get; set; }
public string hair { get; set; }
public string glasses { get; set; }
public Grade[] Grades { get; set; }
}
public class StudentInfo
{
public string name { get; set; }
public string lastname { get; set; }
public Property[] Properties { get; set; }
public string StudentName {
get{ return String.Format ("{0}", name); }
}
//Why isn't the following code work? I am not getting the values and I get errors.
public string HairColor {
get{ return String.Format ("{0}",Property.hair); }
}
public string MathGrade {
get{ return String.Format ("{0}", Property.Grade.Math); }
}
}
public class Rootobject
{
public StudentInfo[] students { get; set; }
}
}
下面是我如何使用学生姓名填充列表视图
var sv = new WebService();
var es = await sv.GetStudentInfoAsync(apiurl);
Xamarin.Forms.Device.BeginInvokeOnMainThread( () => {
listView.ItemsSource = es.students;
});
var cell = new DataTemplate (typeof(TextCell));
listView.ItemTemplate = cell;
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "StudentName");
问题是您正在尝试访问一个名为 Property
的 属性,它在您的 class 中不存在。相反,您的 class 有一个 Property
对象数组:
public Property[] Properties { get; set; }
同样,您的 Property
class 有一个 Grade
对象数组,而不是单个 Grade
:
public Grade[] Grades { get; set; }
因此您必须对数组进行索引才能找到特定的 Property
或 Grade
。如果你总是想在每个数组中使用第一个条目,这可以通过Enumerable.Select
and Enumerable.FirstOrDefault
:
轻松完成
public class StudentInfo
{
public string name { get; set; }
public string lastname { get; set; }
public Property[] Properties { get; set; }
public string StudentName {
get{ return String.Format ("{0}", name); }
}
public string HairColor {
get{ return (Properties ?? Enumerable.Empty<Property>()).Select(p => p.hair).FirstOrDefault(); }
}
public string MathGrade {
get { return (Properties ?? Enumerable.Empty<Property>()).SelectMany(p => p.Grades ?? Enumerable.Empty<Grade>()).Select(g => g.Math).FirstOrDefault(); }
}
}
然后,进行测试:
var root = JsonConvert.DeserializeObject<Rootobject>(response);
Debug.Assert(root.students.Length == 1 && root.students[0].HairColor == "black" && root.students[0].MathGrade == "44"); // No assert.
更新
您不能将“'hair' of all 4 students”作为 StudentInfo
的 属性,因为在您的 JSON 中,每个学生只有一个条目在其 "Properties"
数组中。如果你 post 你的 JSON 到 http://jsonformatter.curiousconcept.com/,你可以更清楚地看到这一点。要获取所有学生的头发颜色或姓名,您需要根对象:
var root = JsonConvert.DeserializeObject<Rootobject>(response);
var hairColors = root.students.Select(s => s.HairColor).ToArray();
var studentNames = root.students.Select(s => s.StudentName).ToArray();
更新 2
在您更新的问题中,单个 "student" 对象确实具有多个头发颜色属性、多个数学成绩等。在这种情况下,如果您希望将它们显示为单个字符串,则需要以某种方式组合它们,例如以逗号分隔值:
public class StudentInfo
{
public string name { get; set; }
public string lastname { get; set; }
public Property[] Properties { get; set; }
public string StudentName
{
get { return name; }
}
public string[] HairColors
{
get
{
return (Properties ?? Enumerable.Empty<Property>()).Select(p => p.hair).ToArray();
}
}
public string HairColorCSV
{
get { return string.Join(",", HairColors); }
}
public string[] MathGrades
{
get
{
return (Properties ?? Enumerable.Empty<Property>()).SelectMany(p => p.Grades ?? Enumerable.Empty<Grade>()).Select(g => g.Math).ToArray();
}
}
public string MathGradeCSV
{
get { return string.Join(",", MathGrades); }
}
}
我更新了 JSON table,如下所示
{ "Students" : [ {"name": "Alex", "lastname": "Dean", "Properties" : [{"iq":120, "hair": "black", "glasses": "yes", "Grades": [{"Math": 44, "Lit": "88"}]}, {"iq":120, "hair": "blond", "glasses": "yes", "Grades" : [{"Math": 22, "Lit": "81"}]}, {"iq":144, "hair": "brown", "glasses": "yes", "Grades": [{"Math": 44, "Lit": "88"}]}, {"iq":120, "hair": "red", "glasses": "yes", "Grades" : [{"Math": 44, "Lit": "88"}]}]}]}
我设法获取了不在子数组中的名字和姓氏,但无法弄清楚如何获取子数组中的其他数据。在数组 "Students" 中有一个名为 "Properties" 的子数组,在 "Properties" 中有另一个名为 "Grades".
的子数组如何获得 "hair" 和 "math" 属性?
这是我获取名字和姓氏的方法。
这是我的网络服务class
public class WebService
{
public WebService ()
{
}
public async Task<Rootobject> GetStudentInfoAsync (string apiurl) {
var client = new HttpClient ();
var response = await client.GetStringAsync(string.Format(apiurl));
return JsonConvert.DeserializeObject<Rootobject>(response.ToString());
}
}
这是我想出的视图模型。为什么它不起作用。我没有得到值。
namespace MyApp
{
public class Grade
{
public string Math { get; set; }
public string Lit { get; set; }
}
public class Property
{
public int iq { get; set; }
public string hair { get; set; }
public string glasses { get; set; }
public Grade[] Grades { get; set; }
}
public class StudentInfo
{
public string name { get; set; }
public string lastname { get; set; }
public Property[] Properties { get; set; }
public string StudentName {
get{ return String.Format ("{0}", name); }
}
//Why isn't the following code work? I am not getting the values and I get errors.
public string HairColor {
get{ return String.Format ("{0}",Property.hair); }
}
public string MathGrade {
get{ return String.Format ("{0}", Property.Grade.Math); }
}
}
public class Rootobject
{
public StudentInfo[] students { get; set; }
}
}
下面是我如何使用学生姓名填充列表视图
var sv = new WebService();
var es = await sv.GetStudentInfoAsync(apiurl);
Xamarin.Forms.Device.BeginInvokeOnMainThread( () => {
listView.ItemsSource = es.students;
});
var cell = new DataTemplate (typeof(TextCell));
listView.ItemTemplate = cell;
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "StudentName");
问题是您正在尝试访问一个名为 Property
的 属性,它在您的 class 中不存在。相反,您的 class 有一个 Property
对象数组:
public Property[] Properties { get; set; }
同样,您的 Property
class 有一个 Grade
对象数组,而不是单个 Grade
:
public Grade[] Grades { get; set; }
因此您必须对数组进行索引才能找到特定的 Property
或 Grade
。如果你总是想在每个数组中使用第一个条目,这可以通过Enumerable.Select
and Enumerable.FirstOrDefault
:
public class StudentInfo
{
public string name { get; set; }
public string lastname { get; set; }
public Property[] Properties { get; set; }
public string StudentName {
get{ return String.Format ("{0}", name); }
}
public string HairColor {
get{ return (Properties ?? Enumerable.Empty<Property>()).Select(p => p.hair).FirstOrDefault(); }
}
public string MathGrade {
get { return (Properties ?? Enumerable.Empty<Property>()).SelectMany(p => p.Grades ?? Enumerable.Empty<Grade>()).Select(g => g.Math).FirstOrDefault(); }
}
}
然后,进行测试:
var root = JsonConvert.DeserializeObject<Rootobject>(response);
Debug.Assert(root.students.Length == 1 && root.students[0].HairColor == "black" && root.students[0].MathGrade == "44"); // No assert.
更新
您不能将“'hair' of all 4 students”作为 StudentInfo
的 属性,因为在您的 JSON 中,每个学生只有一个条目在其 "Properties"
数组中。如果你 post 你的 JSON 到 http://jsonformatter.curiousconcept.com/,你可以更清楚地看到这一点。要获取所有学生的头发颜色或姓名,您需要根对象:
var root = JsonConvert.DeserializeObject<Rootobject>(response);
var hairColors = root.students.Select(s => s.HairColor).ToArray();
var studentNames = root.students.Select(s => s.StudentName).ToArray();
更新 2
在您更新的问题中,单个 "student" 对象确实具有多个头发颜色属性、多个数学成绩等。在这种情况下,如果您希望将它们显示为单个字符串,则需要以某种方式组合它们,例如以逗号分隔值:
public class StudentInfo
{
public string name { get; set; }
public string lastname { get; set; }
public Property[] Properties { get; set; }
public string StudentName
{
get { return name; }
}
public string[] HairColors
{
get
{
return (Properties ?? Enumerable.Empty<Property>()).Select(p => p.hair).ToArray();
}
}
public string HairColorCSV
{
get { return string.Join(",", HairColors); }
}
public string[] MathGrades
{
get
{
return (Properties ?? Enumerable.Empty<Property>()).SelectMany(p => p.Grades ?? Enumerable.Empty<Grade>()).Select(g => g.Math).ToArray();
}
}
public string MathGradeCSV
{
get { return string.Join(",", MathGrades); }
}
}