Reputation: 7950
I already posted a similar question on SO, where I asked, how to consume a REST Api and deserialize the nested JSON Response. I want to use it for an .NET MVC5 web application, but it turned out to be too slow (it takes about 5min for the response). What I'm trying to do now instead is saving the json response to a file and accessing the local file from the web application (I'm also planning to implement caching later).
This is how the JSON Response looks like:
{
"success": true,
"message": "OK",
"types":
[
{
"name": "A5EF3-ASR",
"title": "ITIL Foundation Plus Cloud Introduction",
"classroomDeliveryMethod": "Self-paced Virtual Class",
"descriptions": {
"EN": {
"description": "some Text null",
"overview": null,
"abstract": "Some other text",
"prerequisits": null,
"objective": null,
"topic": null
}
},
"lastModified": "2014-10-08T08:37:43Z",
"created": "2014-04-28T11:23:12Z"
},
{
"name": "A4DT3-ASR",
"title": "ITIL Foundation eLearning Course + Exam",
"classroomDeliveryMethod": "Self-paced Virtual Class",
"descriptions": {
"EN": {
"description": "some Text"
(...)
}
]
}
This is what my POCO classes look like (which work fine, when I consume the rest api):
public class PocoCourse
{
public bool Success { get; set; }
public string Message { get; set; }
public List<PocoCourseType> Types { get; set; }
}
public class PocoCourseType
{
public string Name { get; set; }
public string Title { get; set; }
public string ClassroomDeliveryMethod { get; set; }
public List<PocoCourseTypeDescription> Descriptions { get; set; }
public DateTime LastModified { get; set; }
public DateTime Created { get; set; }
}
public class PocoCourseTypeDescription
{
public List<PocoCourseTypeDescriptionDetails> EN { get; set; }
public List<PocoCourseTypeDescriptionDetails> DE { get; set; }
}
public class PocoCourseTypeDescriptionDetails
{
public string Description { get; set; }
public string Overview { get; set; }
public string Abstract { get; set; }
public string Prerequisits { get; set; }
public string Objective { get; set; }
public string Topic { get; set; }
}
Now, how can I deserialize the content of my JSON file? I tried using JSON.NET (Newtonsoft.Json) to do so:
string filepath = HttpContext.Current.Server.MapPath("~/Files/Courses.json");
using (StreamReader r = new StreamReader(filepath))
{
string json = r.ReadToEnd();
PocoCourse items = JsonConvert.DeserializeObject<PocoCourse>(json);
}
But it throws me the following error:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[CourseProviders.ExternalProviders.PocoCourseTypeDescription]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
How can I fix this?
Upvotes: 0
Views: 4422
Reputation: 14614
According to the json example, your classes definition should be like below
public class PocoCourse
{
public bool Success { get; set; }
public string Message { get; set; }
public List<PocoCourseType> Types { get; set; }
}
public class PocoCourseType
{
public string Name { get; set; }
public string Title { get; set; }
public string ClassroomDeliveryMethod { get; set; }
public PocoCourseTypeDescriptionContainer Descriptions { get; set; }
public DateTime LastModified { get; set; }
public DateTime Created { get; set; }
}
public class PocoCourseTypeDescription
{
public string Description { get; set; }
public string Overview { get; set; }
public string Abstract { get; set; }
public string Prerequisits { get; set; }
public string Objective { get; set; }
public string Topic { get; set; }
}
public class PocoCourseTypeDescriptionContainer
{
public PocoCourseTypeDescription EN { get; set; }
public PocoCourseTypeDescription DE { get; set; }
}
Here's a working example: https://dotnetfiddle.net/uvPV5l
Upvotes: 4