【问题标题】:How to get data from JSON sub array using Newtonsoft.Json?如何使用 Newtonsoft.Json 从 JSON 子数组中获取数据?
【发布时间】:2015-07-02 09:52:20
【问题描述】:

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

{ "学生" : [ {"name": "Alex", "lastname": "Dean", "Properties" : [{"iq":120, "hair": "black", "glasses": “是”,“成绩”:[{“数学”:44,“点燃”:“88”}]},{“iq”:120,“头发”:“金发”,“眼镜”:“是”, “成绩”:[{“数学”:22,“点燃”:“81”}]},{“iq”:144,“头发”:“棕色”,“眼镜”:“是”,“成绩”: [{“数学”:44,“点燃”:“88”}]},{“iq”:120,“头发”:“红色”,“眼镜”:“是”,“成绩”:[{“数学” ": 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());

        }
    }

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

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

【问题讨论】:

  • Properties 数组有什么东西吗?
  • 没有。什么都得不到。

标签: c# json xamarin.forms


【解决方案1】:

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

    public Property[] Properties { get; set; }

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

    public Grade[] Grades { get; set; }

因此,您必须对数组进行索引才能找到特定的PropertyGrade。如果您总是想在每个数组中使用 first 条目,这可以通过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); }
    }
}

【讨论】:

  • 我收到错误当前上下文中不存在名称“Enumerable”。
  • @Carell - 我认为 Linq 以 xamarin 形式提供。尝试添加using System.Linq; 和对System.Core.dll 的引用。见System.Linq namespace doesn't resolve?
  • 谢谢。但这只是获得第一个学生。如何获得所有值?上面我只展示了一个学生,但还有更多。
  • @Carell - 你问,“我如何获得“头发”和“数学”属性?这是你的问题,还是你有不同的问题?因为这是我试图回答的问题。
  • 是的,您确实回答了我的问题,我会接受您的回答。但是如果有多个学生,我该怎么做才能让每个学生的“头发”?
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 2019-09-10
  • 2019-01-05
相关资源
最近更新 更多