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

时间:2015-07-01 01:58:01

标签: c# json xamarin.forms

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

{"学生" :[{" name":" Alex"," lastname":" Dean"," Properties" :[{" iq":120," hair":" black","眼镜":"是", "等级" :[{"数学":44,"点亮":" 88"}]},{" iq":120,&#34 ;":"金发","眼镜":"是","等级" :[{"数学":22,"点亮":" 81"}]},{" iq":144,&#34 ;":"棕色","眼镜":"是","等级" :[{"数学":44,"点亮":" 88"}]},{" iq":120,&#34 ;":"红色","眼镜":"是","等级" :[{"数学":44,"点亮":" 88"}]}]}]}

我设法获得了不在子数组中的名称和姓氏,但无法弄清楚如何获取子数组中的其他数据。阵列内部"学生"有一个名为" Properties"和另一个子阵列"属性"叫"成绩"。

我如何得到"头发"和"数学"特性

以下是我要做的名字和姓氏。

这是我的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());

        }
    }

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

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

1 个答案:

答案 0 :(得分:1)

问题是您正在尝试访问类中不存在的名为Property的属性。相反,您的类有一组Property个对象:

    public Property[] Properties { get; set; }

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

    public Grade[] Grades { get; set; }

因此,您必须为数组编入索引才能找到特定的PropertyGrade。如果总是想要在每个数组中使用第一个条目,则可以使用Enumerable.SelectEnumerable.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); }
    }
}