在C#中使用JSON反序列化为字典

时间:2016-01-24 17:06:57

标签: c# json serialization

我将JSON数据反序列化为字典。这就是我的JSON数据:

{
    "InputKoffRetStats":true,"InputPenaltyStats":false,
    "VisitingTeamFootballRbStats":
         [{
             "AthleteLastName":"John",
             "AthleteFirstName":"Smith","Number":9,"IsPresent":true
         },
         {
             "AthleteLastName":"Justin",
             "AthleteFirstName":"Brooks","Number":10,"IsPresent":false
         }]
}

这就是我将字符串反序列化为字典的方式:

var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);

我遇到的问题是我不知道如何获得第一名运动员的姓氏(约翰)。

如果我这样做:

 Console.WriteLine(dict["InputKoffRetStats"]);

然后我得到&#34; True&#34;。它工作正常。

如果我这样做:

Console.WriteLine(dict["VisitingTeamFootballRbStats"]);

然后我得到了两位运动员(约翰和贾斯汀)的信息。

我怎么能用字典来获得第一个运动员的名字?我尝试了以下操作但没有成功:

Console.WriteLine(dict["VisitingTeamFootballRbStats"][0]);

有什么想法吗?

编辑:我应该提到我展示的json只是整个json的一小部分。我只是举了一个例子。

6 个答案:

答案 0 :(得分:3)

一个完整的工作示例:

public class Athlete
{
    public string AthleteLastName { get; set; }
    public string AthleteFirstName { get; set; }
    public int Number { get; set; }
    public bool IsPresent { get; set; }
}

public class Stat
{
    public bool InputKoffRetStats { get; set; }
    public bool InputPenaltyStats { get; set; }
    public List<Athlete> VisitingTeamFootballRbStats { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var jsonText = "{" +
                        "    \"InputKoffRetStats\":true,\"InputPenaltyStats\":false," +
                        "    \"VisitingTeamFootballRbStats\":" +
                        "         [{" +
                        "             \"AthleteLastName\":\"John\"," +
                        "             \"AthleteFirstName\":\"Smith\",\"Number\":9,\"IsPresent\":true" +
                        "         }," +
                        "         {" +
                        "             \"AthleteLastName\":\"Justin\"," +
                        "             \"AthleteFirstName\":\"Brooks\",\"Number\":10,\"IsPresent\":false" +
                        "         }]" +
                        "}";

        var stat = JsonConvert.DeserializeObject<Stat>(jsonText);

        Console.WriteLine(stat.VisitingTeamFootballRbStats[0].AthleteFirstName);
        Console.ReadKey();
    }
}

PS。:您提供的JSON中存在错误。在您使用"IsPresent"作为布尔值"IsPresent":true之后,下次您将其用作字符串时"IsPresent":No(错误地,因为否应该是&# 34;否&#34)。无论如何,我将其更正为"IsPresent":false

更新:如果您想要&#34;类似于JavaScript&#34;行为,所以你希望能够someObj["someProperty"]["someNestedProperty"]做到这一点:

var stat = JsonConvert.DeserializeObject<JObject>(jsonText);

所以要获得第一位运动员的名字:

var firstName = stat["VisitingTeamFootballRbStats"][0]["AthleteFirstName"].Value<string>();

那就是说,我仍然会为JSON中的所有可能字段创建适当的类。

答案 1 :(得分:1)

反序列化的另一种方法是创建一个如下所示的JsonProperty类:

public class VisitingTeamFootballRbStats
{
    [JsonProperty("AthleteLastName")]
    public string AthleteLastName{ get; set; }

    [JsonProperty("AthleteFirstName")]
    public string AthleteFirstName{ get; set; }

    [JsonProperty("Number")]
    public string Number{ get; set; }

    [JsonProperty("IsPresent")]
    public string IsPresent{ get; set; }
}

然后将其反序列化如下:

List<VisitingTeamFootballRbStats> visitingTeams = JsonConvert.DeserializeObject<List<VisitingTeamFootballRbStats>>(jsonString["VisitingTeamFootballRbStats"].ToString());

因此,一旦您获得列表,您可以轻松获得运动员的详细信息如下:

visitingTeams.ElementAt(0).AthleteLastName;

或者你可以使用linq。

答案 2 :(得分:1)

您的代码不起作用,因为您的json对象不是字典,它是自定义对象 它在这里看起来是一个序列化的词典

{"team1":[{"AthleteLastName":"v2",
"AthleteFirstName":"v1",
"Number":2,
"IsPresent":false}]}

这是一个完全有效的例子

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
           var team=  "{" +
                       "    \"InputKoffRetStats\":true,\"InputPenaltyStats\":false," +
                       "    \"VisitingTeamFootballRbStats\":" +
                       "         [{" +
                       "             \"AthleteLastName\":\"John\"," +
                       "             \"AthleteFirstName\":\"Smith\",\"Number\":9,\"IsPresent\":true" +
                       "         }," +
                       "         {" +
                       "             \"AthleteLastName\":\"Justin\"," +
                       "             \"AthleteFirstName\":\"Brooks\",\"Number\":10,\"IsPresent\":false" +
                       "         }]" +
                       "}";





            var desTeam = JsonConvert.DeserializeObject<Team>(team);  
            Console.WriteLine(desTeam.VisitingTeamFootballRbStats[0].AthleteFirstName);



        }
    }

    public class Team{
        public bool InputKoffRetStats { get; set; }
        public bool InputPenaltyStats { get; set; }
        public  List<AthleteInfo> VisitingTeamFootballRbStats { get; set; }

    }

    public class AthleteInfo
    {
        public string AthleteLastName { get; set; }
        public string AthleteFirstName { get; set; }
        public int Number { get; set; }
        public bool IsPresent { get; set; }
    }
}

<强>更新

如果你使用webapi / wcf,你可以要求数据合同,否则你可以使用动态对象

注意 通过使用动态对象,你可以放弃智能感知的支持

代码

//same json string  

 dynamic desDynTeam = JObject.Parse(team);     
             Console.WriteLine(desDynTeam.VisitingTeamFootballRbStats[0].AthleteLastName); 

答案 3 :(得分:1)

VisitingTeamFootballRbStats数组变得很长,或者JSON中的外部还有其他字段。如果JSON是已知的并且不会改变,我仍然会在我的.NET项目中添加适当的类并反序列化。

答案 4 :(得分:0)

dict["VisitingTeamFootballRbStats"][0]可以获取整个Athlete对象。

要使用名称,请使用.AthleteFirstName

像这样:

dict["VisitingTeamFootballRbStats"][0].AthleteFirstName

答案 5 :(得分:0)

您是否在.NET中查看了dynamics?这是一个使用Newtonsoft.Json的简单控制台应用程序,它显示了如何在JSON对象上访问这些属性:

static void Main(string[] args)
{
    dynamic dObject = JObject.Parse(json);

    Console.WriteLine(dObject.VisitingTeamFootballRbStats[0].AthleteLastName); 
    //Prints "John"

    Console.ReadLine();
}

private static string json = @"
    {
        'InputKoffRetStats':true,'InputPenaltyStats':false,
        'VisitingTeamFootballRbStats':
        [{
            'AthleteLastName':'John',
            'AthleteFirstName':'Smith','Number':9,'IsPresent':true
        },
        {
            'AthleteLastName':'Justin',
            'AthleteFirstName':'Brooks','Number':10,'IsPresent':false
        }]
    }
    ";