Question

I need to deserialize some JSON but the problem is that all of my JSON objects don't have the exact same format. Here is an example of the JSON that I have to deserialize :

[
  {
    "Player_Name": "Zlatan Ibrahimovic",
    "Country": "Sweeden",
    "Other_Informations": {
      "Information1": [

      ]
    },
  },
   {
    "Player_Name": "Pavel Nedved",
    "Country": "Czech Republic",
    "Personal_Honours": 
        {
            "Ballon_DOr": "One",
        },
    "Other_Informations": {
      "Information1": [

      ]
    },
  },
   {
    "Player_Name": "Zinedine Zidane",
    "Country": "Sweeden",
    "Other_Informations": {
      "Information1": [
        {
          "name": "example",
        }
      ]
    },
  }
 ]

As you can see, some fields appear only for some objects for example "Personal_Honours". I need to deserialize the JSON into this class :

public class PlayerData
{
    public string Name { get; set; }
    public string BallonDor {get; set; }
    public string Information1{ get; set; }
    public string Country{ get; set; }
}

I use this method which is really long and blocks my app : (In this exmple I use Json that comes frome a textfile but usually I have to make a REST request..)

StreamReader reader = File.OpenText("TextFile1.txt");
List<PlayerData> DataList;
dynamic value= JsonConvert
    .DeserializeObject<dynamic>(reader.ReadToEnd());


DataList = new List<PlayerData>();
    foreach (dynamic data in value)
                    {

                        if (data.Personal_Honours == null)
                        {
                            if (data.Other_Informations.Information1 == null)
                            {
                                DataList.Add(new PlayerData
                                {
                                    Name = data.Player_Name,
                                    Country = data.Country,
                                });
                            }
                            else                            
                            {
                                DataList.Add(new PlayerData
                                {
                                    Name = data.Player_Name,
                                    Country = data.Country,
                                    Information1 = data.Informations.Information1
                                });

                            }

                        }
                        else 
                        {
                            if (data.Other_Informations.Information1 == null)
                            {

                                DataList.Add(new PlayerData
                                {
                                    Name = data.Player_Name,
                                    Country = data.Country,
                                    BallonDor = data.Personal_Honours.Ballon_DOr

                                });
                            }
                            else 
                            {
                                DataList.Add(new PlayerData
                                {
                                    Name = data.Player_Name,
                                    Country = data.Country,
                                    BallonDor = data.Personal_Honours.Ballon_DOr,
                                    Information1 = data.Informations.Information1

                                });

                            }

                        }

                    }

This method is working but it is not efficient and blocks my UI. How can I do to create a new "PlayerData" object without having all of those 'else if' statements ?
Thank you !

P.S : The question is different from this one Filter JSon Information

EDIT :

Here is how I got the RunTimeBinderExcepetion :

 List<PlayerData> datalist = new List<PlayerData>();

    foreach (dynamic pl in timeline)
    {



        datalist.Add(new PlayerData 
        { 

         Name  = pl.Player_Name , 
         Country = pl.Country ,
          BallonDor = pl.Personal_Honours.Ballon_Dor,
           Information1 = pl.Other_Informations.Information1.name

        });
    }
Was it helpful?

Solution

You got exception because some data doesn't have Personal_Honours property for example. Then you tried to access Ballon_Dor property from a null reference which trigger the exception. This way will work for sample JSON you posted :

List<PlayerData> datalist = new List<PlayerData>();
foreach (dynamic pl in timeline)
{
    //object initialization is done later just for the sake of easier debugging
    //...so we can spot unexpected data which cause exception easily
    var Name = pl.Player_Name;
    var Country = pl.Country;
    var BallonDor = pl.Personal_Honours != null ? pl.Personal_Honours.Ballon_Dor : null;
    var Information1 = pl.Other_Informations.Information1.Count > 0 ? 
                                pl.Other_Informations.Information1[0].name : 
                                null;
    datalist.Add(new PlayerData 
    { 
        Name  = Name , 
        Country = Country ,
        BallonDor = BallonDor,
        Information1 = Information1
    });
}

...but above approach is still error prone depending on how consistent is the JSON string we have. More robust approach is maybe to have model classes to map JSON string as suggested by @L.B in comment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top