【问题标题】:C# How to handle NULL json values? Getting and InvalidOperationException: Cannot access child value on > Newtonsoft.Json.Linq.JValueC# 如何处理 NULL json 值?获取和 InvalidOperationException:无法访问 > Newtonsoft.Json.Linq.JValue 上的子值
【发布时间】:2017-10-24 22:21:30
【问题描述】:

我在处理 json 文件中的空值时遇到问题。正如您在下图中看到的,null 值位于 player 下方:

不幸的是,这导致了以下 InvalidOperationException:

System.InvalidOperationException:无法访问子值 Newtonsoft.Json.Linq.JValue。 在 Newtonsoft.Json.Linq.JToken.get_Item(对象键) 在 C:\Users\Administrator\documents\visual studio 中的 WindowsFormsApplication2.Starting_Lineups.StartingLineups() 2015\Projects\WindowsFormsApplication2\WindowsFormsApplication2\Starting Lineups.cs:第 97 行

我尝试了以下How to ignore a property in class if null, using json.net,但没有成功。

JSON:

{"gamestartinglineup":{"lastUpdatedOn":"2017-10-24 11:41:12 AM","game":{"id":"42120","date":"2017-10-24","time":"7:30PM","awayTeam":{"ID":"83","City":"New York","Name":"Knicks","Abbreviation":"NYK"},"homeTeam":{"ID":"82","City":"Boston","Name":"Celtics","Abbreviation":"BOS"},"location":"TD Garden"},"teamLineup":[{"team":{"ID":"83","City":"New York","Name":"Knicks","Abbreviation":"NYK"},"expected":{"starter":[{"position":"Bench8","player":null},{"position":"Starter1","player":{"ID":"9087","LastName":"Hardaway Jr.","FirstName":"Tim","JerseyNumber":"3","Position":"SG"}},{"position":"Starter2","player":{"ID":"9373","LastName":"Porzingis","FirstName":"Kristaps","JerseyNumber":"6","Position":"PF"}},{"position":"Starter5","player":{"ID":"9518","LastName":"Sessions","FirstName":"Ramon","JerseyNumber":"1","Position":"PG"}},{"position":"Starter3","player":{"ID":"9396","LastName":"Kanter","FirstName":"Enes","JerseyNumber":"0","Position":"C"}},{"position":"Starter4","player":{"ID":"9127","LastName":"Lee","FirstName":"Courtney","JerseyNumber":"1","Position":"SG"}},{"position":"Bench1","player":{"ID":"9148","LastName":"McDermott","FirstName":"Doug","JerseyNumber":"20","Position":"SF"}},{"position":"Bench2","player":{"ID":"9376","LastName":"O'Quinn","FirstName":"Kyle","JerseyNumber":"9","Position":"PF"}},{"position":"Bench3","player":{"ID":"9245","LastName":"Beasley","FirstName":"Michael","JerseyNumber":"9","Position":"F"}},{"position":"Bench4","player":{"ID":"10102","LastName":"Baker","FirstName":"Ron","JerseyNumber":"31","Position":"G"}},{"position":"Bench5","player":null},{"position":"Bench6","player":null},{"position":"Bench7","player":null}]},"actual":null},{"team":{"ID":"82","City":"Boston","Name":"Celtics","Abbreviation":"BOS"},"expected":{"starter":[{"position":"Bench8","player":null},{"position":"Starter1","player":{"ID":"13730","LastName":"Tatum","FirstName":"Jayson","JerseyNumber":"0","Position":"F"}},{"position":"Starter2","player":{"ID":"9082","LastName":"Horford","FirstName":"Al","JerseyNumber":"15","Position":"C"}},{"position":"Starter5","player":{"ID":"9157","LastName":"Irving","FirstName":"Kyrie","JerseyNumber":"11","Position":"PG"}},{"position":"Starter3","player":{"ID":"9211","LastName":"Baynes","FirstName":"Aron","JerseyNumber":"12","Position":"C"}},{"position":"Starter4","player":{"ID":"10090","LastName":"Brown","FirstName":"Jaylen","JerseyNumber":"7","Position":"SF"}},{"position":"Bench1","player":{"ID":"13777","LastName":"Theis","FirstName":"Daniel","JerseyNumber":"27","Position":"PF"}},{"position":"Bench2","player":{"ID":"9105","LastName":"Rozier","FirstName":"Terry","JerseyNumber":"12","Position":"PG"}},{"position":"Bench3","player":{"ID":"13770","LastName":"Nader","FirstName":"Abdel","JerseyNumber":"28","Position":"SF"}},{"position":"Bench4","player":{"ID":"9120","LastName":"Larkin","FirstName":"Shane","JerseyNumber":"8","Position":"PG"}},{"position":"Bench5","player":{"ID":"13778","LastName":"Yabusele","FirstName":"Guerschon","JerseyNumber":"30","Position":"PF"}},{"position":"Bench6","player":{"ID":"13771","LastName":"Bird","FirstName":"Jabari","JerseyNumber":"26","Position":"SG"}},{"position":"Bench7","player":null}]},"actual":null}]}}

代码:

    public void StartingLineups()
    {
        upass.upass up = new upass.upass();
        string address3 = "https://api.mysportsfeeds.com/v1.1/pull/nba/2017-2018-regular/game_startinglineup.json?gameid=" + dateTimePicker1.Text + comboBox2.Text;

        var w3 = new WebClient();
        w3.UseDefaultCredentials = true;
        w3.Credentials = new NetworkCredential(up.username, up.password);
        var result3 = w3.DownloadString(address3);

        var obj3 = JObject.Parse(result3);


        StartingLineup.startinglineup sl = new StartingLineup.startinglineup();

        try
       {

            foreach (JToken child in obj3 ["gamestartinglineup"]["teamLineup"])
            {


                    foreach (JToken sub in child["expected"]["starter"])
                    {

                    JsonConvert.SerializeObject(sub,
                        Newtonsoft.Json.Formatting.None,
                        new JsonSerializerSettings
                        {
                            NullValueHandling = NullValueHandling.Ignore
                        });

                    sl.player = sub["player"]["FirstName"].ToString() + " " + sub["player"]["LastName"].ToString();
                        sl.team = child["team"]["City"].ToString() + " " + child["team"]["Name"].ToString();
                        sl.position = sub["position"].ToString();
                        sl.playerpositon = sub["player"]["Position"].ToString();




                        DataRow row = dt.NewRow();
                        row["Team"] = sl.team;
                        row["Player"] = sl.player;
                        row["Position"] = sl.playerpositon;





                        if (sl.position.Contains("Starter"))
                        {
                            row["Role"] = sl.position;
                        }
                        else
                        {
                            row["Role"] = "NOPE";
                        }



                        dt.Rows.Add(row);
                    }
                    dataGridView1.DataSource = dt;

                    DataRow[] drr = dt.Select("Role='NOPE'");
                    for (int i = 0; i < drr.Length; i++)
                        drr[i].Delete();
                    dt.AcceptChanges();




                }



        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());

        }

    }

【问题讨论】:

  • 为什么对JsonConvert.SerializeObject(sub, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });的输出字符串什么都不做?
  • 您仍然需要检查是否为空。这与期待myNullObject.ChildProperty 成功没有什么不同。 NullValueHandling.Ignore只是表示如果值为null,则序列化为JSON时该属性将不存在。

标签: c# json


【解决方案1】:

在检查可空值时考虑这一点 (Value<T>(Object key)):

var testObj = new Newtonsoft.Json.Linq.JObject();

if (testObj.TryGetValue("player", out Newtonsoft.Json.Linq.JToken token)) {
 string yourString = token.Value<string>("FirstName"); // can be null
 int? yourNullableInt = token.Value<int?>("AnyNumber"); // can be null
 int yourInt = token.Value<int?>("AnyNumber") ?? 0; // can be 0 if null
 int yourInt = token.SelectToken("firstLayer")?.SelectToken("secondLayer")?.Value<int?>("anyNumber") ?? 0; // return value by path
}

SelectToken 也适用于Newtonsoft.Json.Linq.JObject

【讨论】:

    猜你喜欢
    • 2018-12-19
    • 2021-01-23
    • 2021-08-09
    • 1970-01-01
    • 2019-08-24
    • 2021-08-21
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    相关资源
    最近更新 更多