简体   繁体   中英

Deserialization of JSON in C# into an object for API

I am trying to get data from an API for an assignment, but i've gotten stuck along the way. I am fairly inexperienced in C# and have only really used Java and PHP before, but I would say my experience with both are also fairly limited (simple mysqli CRUD via PHP webforms and playing around with Java logic, made a few small games etc.), therefore I probably don't really know what I'm doing wrong or where the problem lies.

For some reason the JSON isn't deserialized in the code below.

Console.WriteLine(driversCollection.Drivers.Count); always returns null when attempting to count it. It does download the JSON properly from what I could tell after putting down a breakpoint in visual studio and seeing the local rawJSON value had been updated. I believe the JSON itself is wrongly formatted and have tried removing the backslashes by using Replace, which also doesn't work.

This is the link to the JSON: https://ergast.com/api/f1/drivers.json?callback=myParser

I apologize in advance for my subpar code and what is probably a simple solution, though I would be extremely grateful for any help I could get on this.

Drivers.cs

public class Drivers
    {
        string driverID;
        int permanentNumber;
        string code;
        string url;
        string givenName;
        string familyName;
        string dateOfBirth;
        string nationality;

        public string DriverID { get => driverID; set => driverID = value; }
        public int PermanentNumber { get => permanentNumber; set => permanentNumber = value; }
        public string Code { get => code; set => code = value; }
        public string Url { get => url; set => url = value; }
        public string GivenName { get => givenName; set => givenName = value; }
        public string FamilyName { get => familyName; set => familyName = value; }
        public string DateOfBirth { get => dateOfBirth; set => dateOfBirth = value; }
        public string Nationality { get => nationality; set => nationality = value; }
    }

DriversCollection.cs

    public class DriversCollection
    {
        private List<Drivers> drivers;

        public List<Drivers> Drivers { get => drivers; set => drivers = value; }
    } 

ReadJSON.aspx.cs

    public partial class ReadJSON : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            using (var webClient = new WebClient())
            {
                String rawJSON = webClient.DownloadString("http://ergast.com/api/f1/2019/drivers.json?callback=myParser&limit=1000");
                String editedJSON = rawJSON.Remove(rawJSON.Length - 1, 1);
                editedJSON = editedJSON.Remove(0, 9);
                editedJSON = editedJSON.Replace(@"\/", "/");
                editedJSON = editedJSON.Replace(@"\", string.Empty);
                DriversCollection driversCollection = JsonConvert.DeserializeObject<DriversCollection>(editedJSON);

                Console.WriteLine(driversCollection.Drivers.Count);
            }
        }
    }

The problem is that you're casting the JSON you get back into the DriversCollection class when the JSON is incompatible with the MRData object you get back from the server. You want MRData.DriverTable.Drivers, but are trying to fetch MRData.Drivers

You can achieve it by first parsing it into JObject and then deserializing the DriverTable from this JObject.

 using (var webClient = new WebClient())
        {
            String rawJSON = webClient.DownloadString("http://ergast.com/api/f1/2019/drivers.json?callback=myParser&limit=1000");
            String editedJSON = rawJSON.Remove(rawJSON.Length - 1, 1);
            editedJSON = editedJSON.Remove(0, 9);
            editedJSON = editedJSON.Replace(@"\/", "/");
            editedJSON = editedJSON.Replace(@"\", string.Empty);
            JObject data = JObject.Parse(editedJSON);
            DriversCollection driversCollection = JsonConvert.DeserializeObject<DriversCollection>(data["MRData"]["DriverTable"].ToString());

            Console.WriteLine(driversCollection.Drivers.Count);
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM