c# - 如何使用 Newtonsoft.Json 从 JSON 子数组中获取数据?

标签 c# json xamarin.forms

我有一个更新后的 JSON 表,如下所示

{ "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, "点亮": "88"}]}]}]}

我设法获取了不在子数组中的名字和姓氏,但无法弄清楚如何获取子数组中的其他数据。在数组“Students”中有一个名为“Properties”的子数组,在“Properties”中有另一个名为“Grades”的子数组。

如何获得“头发”和“数学”属性?

这是我获取名字和姓氏的方法。

这是我的 WebService 类

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());

        }
    }

这是我想出的 View 模型。为什么它不起作用。我没有得到这些值。

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; }

    }
}

下面是我如何使用学生姓名填充 ListView

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 的属性,该属性在您的类中不存在。相反,您的类有一个 Property 对象数组:

    public Property[] Properties { get; set; }

同样,您的 Property 类有一组 Grade 对象,而不是单个 Grade:

    public Grade[] Grades { get; set; }

因此,您必须对数组进行索引才能找到特定的 PropertyGrade。如果您总是想在每个数组中使用第一个 条目,可以使用Enumerable.Select 轻松完成。和 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.

更新

您无法将“所有 4 名学生的‘头发’”作为 StudentInfo 的属性,因为在您的 JSON 中,每个学生在其 “Properties” 数组。如果将 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

在您更新的问题中,确实出现了单个“学生”对象具有多个头发颜色属性、多个数学成绩等。在这种情况下,如果您希望将它们显示为单个字符串,则需要以某种方式组合它们,例如以逗号分隔值:

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); }
    }
}

关于c# - 如何使用 Newtonsoft.Json 从 JSON 子数组中获取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31151406/

相关文章:

c# - 从 IEnumerable 到 List 的强制转换无效

c# - JSON 数据无法在 jQuery 中正确序列化

c# - winforms:使用 parallel.foreach 更新进度

c# - WCF RIA 服务超时

listview - 滚动 ListView 直到 xamarin.forms 中的最终项目时应用程序崩溃

javascript - 当表单在数组中提交其获取JSON数据但显示错误时

我可以通过 C 套接字发送 json 数据吗?

c# - 从 SQL Server 查询 C# 中的 JSON

c# - 如何使用 Xamarin Form 以编程方式在现有网格上添加按钮或标签?

c# - Xamarin PCL Android 应用程序在 Release模式下突然崩溃