2014-11-18 4 views
0

Я уже разместил similar question на SO, где я спросил, как использовать REST Api и десериализовать вложенный ответ JSON. Я хочу использовать его для веб-приложения .NET MVC5, но оказалось, что он слишком медленный (для ответа требуется около 5 минут). Вместо этого я пытаюсь сохранить json-ответ на файл и получить доступ к локальному файлу из веб-приложения (я также планирую реализовать кэширование позже).Deserialize inested JSON Response with JSON.NET

Это как JSON ответ выглядит следующим образом:

{ 
    "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" 
      (...) 
    } 
    ] 
} 

Это то, что мои классы POCO похожи (которые работают хорошо, когда я потребляю АНИ остальное):

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; } 
} 

Теперь, как я могу десериализовать содержимое моего файла JSON? Я попытался с помощью Json.NET (Newtonsoft.Json), чтобы сделать так:

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); 
} 

Но он бросает мне следующую ошибку:

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.

Как я могу это исправить?

ответ

4

Согласно JSon примеру, ваше определение классов должно быть, как показано ниже

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; } 
} 

Вот рабочий пример: https://dotnetfiddle.net/uvPV5l

+0

спасибо за Ваш ответ. Извините, я опубликовал старую версию классов в своем оригинальном посте. Я создал еще одну скрипку, содержащую текущие классы poco: https://dotnetfiddle.net/JxTf6l Это по-прежнему та же ошибка, что и в OP. Любые идеи, почему? – Ronin

+0

Я обновил [мою скрипку] (https://dotnetfiddle.net/uvPV5l), проблема с вашей скрипкой - это класс 'PocoCourseTypeDescription', тип свойств' EN' и 'DE' не должен быть« списком » '' поскольку 'EN' не является массивом в примере json. – ekad

+0

Большое спасибо! Это сделал трюк! ты замечательный! – Ronin