我连接到第三方Web服务,该服务返回一个复杂的JSON对象,该对象仅包含我实际需要的一些信息。
基本上,我只需要“值”中的数组。从那个数组中,我只需要“Id”,“Title”和“Status”属性。
我想将这些属性放入名为Project的c#类中。这是我的班级:
public class Project
{
public String Id { get; set; }
public String Title { get; set; }
public String Status { get; set; }
}
我正在尝试使用此代码来读取JSON并执行转换:
using (WebResponse response = request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var serializer = new JsonSerializer();
var jsonTextReader = new JsonTextReader(reader);
returnValue = serializer.Deserialize<Project>(jsonTextReader);
}
}
示例JSON:
{
"odata.metadata":"http://school.edu/Api/1/$metadata#Projects",
"odata.count":"3",
"value":[
{
"odata.id":"http://school.edu/Api/1/Projects('123')",
"RelatedProjects@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('123')/RelatedProjects",
"Tags@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('123')/Tags",
"TimedEvents@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('123')/Categories",
"ep@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('123')/ep",
"#CreateLike":{
"target":"http://school.edu/Api/1/Projects('123')/CreateLike"
},
"#CreateShortcut":{
"target":"http://school.edu/Api/1/Projects('123')/CreateShortcut"
},
"#Play":{
"target":"http://school.edu/Play/123"
},
"#SendInvitation":{
"target":"http://school.edu/Api/1/Projects('123')/SendInvitation"
},
"#CopyProject":{
"target":"http://school.edu/Api/1/Projects('123')/CopyProject"
},
"#AddVideoPodcast":{
"target":"http://school.edu/Api/1/Projects('123')/AddVideoPodcast"
},
"#AddEP":{
"target":"http://school.edu/Api/1/Projects('123')/AddEP"
},
"Id":"123",
"Title":"Test Title 1",
"Status":"Viewable"
},
{
"odata.id":"http://school.edu/Api/1/Projects('456')",
"RelatedProjects@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('456')/RelatedProjects",
"Tags@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('456')/Tags",
"TimedEvents@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('456')/Categories",
"ep@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('456')/ep",
"#CreateLike":{
"target":"http://school.edu/Api/1/Projects('456')/CreateLike"
},
"#CreateShortcut":{
"target":"http://school.edu/Api/1/Projects('456')/CreateShortcut"
},
"#Play":{
"target":"http://school.edu/Play/456"
},
"#SendInvitation":{
"target":"http://school.edu/Api/1/Projects('456')/SendInvitation"
},
"#CopyProject":{
"target":"http://school.edu/Api/1/Projects('456')/CopyProject"
},
"#AddVideoPodcast":{
"target":"http://school.edu/Api/1/Projects('456')/AddVideoPodcast"
},
"#AddEP":{
"target":"http://school.edu/Api/1/Projects('456')/AddEP"
},
"Id":"456",
"Title":"Test Title 2",
"Status":"Viewable"
},
{
"odata.id":"http://school.edu/Api/1/Projects('789')",
"RelatedProjects@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('789')/RelatedProjects",
"Tags@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('789')/Tags",
"TimedEvents@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('789')/Categories",
"ep@odata.navigationLinkUrl":"http://school.edu/Api/1/Projects('789')/ep",
"#CreateLike":{
"target":"http://school.edu/Api/1/Projects('789')/CreateLike"
},
"#CreateShortcut":{
"target":"http://school.edu/Api/1/Projects('789')/CreateShortcut"
},
"#Play":{
"target":"http://school.edu/Play/789"
},
"#SendInvitation":{
"target":"http://school.edu/Api/1/Projects('789')/SendInvitation"
},
"#CopyProject":{
"target":"http://school.edu/Api/1/Projects('789')/CopyProject"
},
"#AddVideoPodcast":{
"target":"http://school.edu/Api/1/Projects('789')/AddVideoPodcast"
},
"#AddEP":{
"target":"http://school.edu/Api/1/Projects('789')/AddEP"
},
"Id":"789",
"Title":"Test Title 3",
"Status":"Viewable"
}
],
"odata.nextLink":"http://school.edu/Api/1/Folders('xyz')/Projects?$skip=10&$top=10"
}
我只是得到一个null对象。但是在调试器中,我可以看到它正在从Web服务中提取所有JSON数据。
如何从JSON中获取所需内容,构建我的c#对象,并忽略所有其余内容?
答案 0 :(得分:5)
如果你可以使用Json.NET
(Newtonsoft json),你可以像这样使用Linq-to-Json
[1]
//using Newtonsoft.Json.Linq;
var jsonString = File.ReadAllText(@"C:YourDirectory\file.json"); //source
var projects = new List<Project>(); //Your result
JObject data = JObject.Parse(jsonString);
foreach (var value in data["value"])
{
projects.Add(new Project
{
Id = value["Id"].ToString(),
Status = value["Status"].ToString(),
Title = value["Title"].ToString()
});
}
或者,您也可以像{2]
那样反序列化JObject
var jsonReader = data["value"].CreateReader();
projects = new JsonSerializer().Deserialize<List<Project>>(jsonReader);
两者都很好,但哪一个更好?
第二种方法意味着更少的代码(特别是,如果在Project
类中有许多属性,那么您必须编写许多代码行来映射代码[1]中的每个属性)。
但第一种方法的表现要好很多倍!对于给定的json数据,代码[1]大致以 1 ms 运行,而代码[2]大于 100 ms !
<强>更新强>
在 James Newton-King(编写Json.NET之后)的输入之后,还有另一种更优雅的方式[3]
projects = data["value"].ToObject<List<Project>>();
猜猜是什么!这个代码[3]接近[强>半] 接近[1]。因此,从各方面来看,这必须是最好的方法!