我想使用REST Api并反序列化嵌套的JSON响应。为此,我尝试创建一些代表JSON响应的POCO类[1]。 响应如下:
{
"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 Course
{
public bool success { get; set; }
public string Message { get; set; }
public List<CourseTypeContainer> Type { get; set; }
}
/* each Course has n CourseTypes */
public class CourseType
{
public string Name { get; set; }
public string Title { get; set; }
public List<CourseTypeDescriptionContainer> Descriptions { get; set; }
public DateTime LastModified { get; set; }
public DateTime Created { get; set; }
}
public class CourseTypeContainer
{
public CourseType CourseType { get; set; }
}
/* each CourseType has n CourseTypeDescriptions */
public class CourseTypeDescription
{
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 CourseTypeDescriptionContainer
{
public CourseTypeDescription CourseTypeDescription { get; set; }
}
这是API代码:
var client = new RestClient("https://www.someurl.com");
client.Authenticator = new HttpBasicAuthenticator("user", "password");
var request = new RestRequest();
request.Resource = "api/v1.0/types";
request.Method = Method.GET;
request.RequestFormat = DataFormat.Json;
var response = client.Execute<Course>(request);
编辑1 :我发现错字,AvnetCourse中的Type
属性应命名为Types
:
public List<AvnetCourseTypeContainer> Type { get; set; } // wrong
public List<AvnetCourseTypeContainer> Types { get; set; } // correct
现在返回值如下:
response.Data.success = true // CORRECT
repsonse.Data.Message = "OK" // CORRECT
response.Data.Types = (Count: 1234); // CORRECT
response.Data.Types[0].AvnetCourseType = null; // NOT CORRECT
编辑2 :我使用Course.Types
而不是List<CourseType>
实施了List<CourseTypeContainer>
属性,正如 Jaanus 即可。 CourseTypeDescriptionContainer
:
public List<CourseTypeContainer> Type { get; set; } // OLD
public List<CourseTypeDescriptionContainer> Descriptions { get; set; } // OLD
public List<CourseType> Type { get; set; } // NEW
public List<CourseTypeDescription> Descriptions { get; set; } // NEW
现在response.Data.Types
最终被正确填充。但是,response.Data.Types.Descriptions仍未正确填充,因为还有一个额外的语言层(例如&#34; EN&#34;)。如何在不为每种语言创建PACO的情况下解决这个问题?
编辑3 :我必须添加一个额外的CourseTypeDescriptionDetails类,我将存储描述性数据。在我的CourseTypeDescription中,我为每种语言添加了类型列表的属性。代码段:
public class AvnetCourseType
{
public List<CourseTypeDescription> Descriptions { get; set; }
// other properties
}
public class CourseTypeDescription
{
public List<CourseTypeDescriptionDetails> EN { get; set; } // English
public List<CourseTypeDescriptionDetails> NL { get; set; } // Dutch
}
public class CourseTypeDescriptionDetails
{
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; }
}
现在可以使用,但是我需要为每种语言的CourseTypeDescription添加另一个属性。
OLD:返回值为
response.Data.success = true // CORRECT
repsonse.Data.Message = "OK" // CORRECT
response.Data.Type = null; // WHY?
那么为什么我的response.Type等于null?我做错了什么?
谢谢
答案 0 :(得分:2)
尝试将其用作POCO:
public class Course
{
public bool success { get; set; }
public string message { get; set; }
public List<CourseTypeContainer> Types { get; set; }
}
现在您有CourseTypeContainer
的列表。
CourseTypeContainer
是
public class CourseTypeContainer
{
public CourseType CourseType { get; set; }
}
因此,当您尝试获取response.Data.Types[0].AvnetCourseType
时,您需要在AvnetCourseType
CourseTypeContainer
或者我认为你想要的实际上是这个公共List<CourseType> Types { get; set; }
,你不需要那里的容器。
答案 1 :(得分:0)
以防万一这对其他人有帮助,我在这里尝试了所有操作,但仍无法在当前版本的RestSharp(106.6.2)上运行。据我所知,RestSharp完全忽略了RootElement属性,即使它位于顶层。我的解决方法是手动告诉它提取嵌套的JSON,然后进行转换。我使用JSON.Net来完成此任务。
var response = restClient.Execute<T>(restRequest);
response.Content = JObject.Parse(response.Content)[restRequest.RootElement].ToString();
return new JsonDeserializer().Deserialize<T>(response);
答案 2 :(得分:0)
我使用http://json2csharp.com/从JSON创建C#类。 然后,将RootObject重命名为我正在创建的模型文件的ClassName 在RestSharp Deserializitaion之后,类似于responseBody.data.Subject.Alias,可访问嵌套json中的所有数据。 数据,主题和别名是在收到的响应JSON中的嵌套节点。