简体   繁体   中英

Deserializing multiple Json objects from URL to List<T> in c#

I am trying to deserialize multiple Json objects from an API call like this: http://jservice.io/api/clues?category=2537&value=400

But when I run my code, I never get past the Json conversion and nothing is returned to the client when calling the GetQuestions() method.

I wanted to save the id, question, answer and value in a custom c# object so I made this class:

public class JsonQuestion
{
    private DataContainer container;
    public int id { get; set; }
    public string answer { get; set; }
    public string question { get; set; }
    public int value { get; set; }
    public JsonQuestion(string categoryId, int value)
    {
        using (var webClient = new System.Net.WebClient())
        {
            var json = webClient.DownloadString("http://jservice.io/api/clues?category=" + categoryId + "&value=" + value);
            container = JsonConvert.DeserializeObject<DataContainer>(json);
        }
    }
    public DataContainer GetQuestions()
    {
        return container;
    }
}

Here I am receiving the categoryID and value to the constructor and then creating the URL based on those values to be deserialized. Ideally I want to return the container holding all the questions to a client. I made a class that holds all the questions received:

public class DataContainer
{
    public List<JsonQuestion> Questions { get; set; }
}

Which I use with the DeserializeObject call.

First of all you have wrong idea of how json will deserialize arrays. If you would look at exceptions that is throwing in your code you would get your first mistake:

Additional information: Cannot deserialize the current JSON array (eg [1,2,3]) into type 'Application.Program+DataContainer' because the type requires a JSON object (eg {"name":"value"}) to deserialize correctly.

To fix this error either change the JSON to a JSON object (eg {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (eg ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

What you are trying to do is deserialize array into object, witch is not possible. So you would need structure of json like this: {"Questions":[content of your json]}. To avoid this you have to change your deserialization to:

JsonConvert.DeserializeObject<List<JsonQuestion>>(json);

Second , JsonConvert will take simplest constructor provided, and will try to use it to create nested sturctures, witch you have multiple. So every time constructor has to be called, JsonConvert will use public JsonQuestion(string categoryId, int value) with fallowing values of null, and 400 (those value are taken form nested item, witch has parameter value set to 400 and no parameter categoryId). So you will fall into recuring loop, becase every time new json document will be downloaded. What you have to do is provide public default constructor of JsonQuestion.

Whole code would look like this:

    public class JsonQuestion
    {
        private List<JsonQuestion> container;
        public int id { get; set; }
        public string answer { get; set; }
        public string question { get; set; }
        public int value { get; set; }
        public JsonQuestion()
        {

        }
        public JsonQuestion(string categoryId, int value)
        {
            using (var webClient = new System.Net.WebClient())
            {
                var json = webClient.DownloadString("http://jservice.io/api/clues?category=" + categoryId + "&value=" + value);
                var container = JsonConvert.DeserializeObject<List<JsonQuestion>>(json);
            }
        }
        public DataContainer GetQuestions()
        {
            return new DataContainer
            {
                Questions = container,
            };
        }
    }

    public class DataContainer
    {
        public List<JsonQuestion> Questions { get; set; }
    }

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