我连接到第三方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",{ "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#对象,并忽略所有其余的东西?
解决方法
如果你可以使用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() }); }
或者,您也可以像这样反序列化JObject [2]
var jsonReader = data["value"].CreateReader(); projects = new JsonSerializer().Deserialize<List<Project>>(jsonReader);
两者都很好,但哪一个更好?
第二种方法意味着更少的代码(特别是,如果在Project类中有许多属性,则必须编写许多代码行来映射代码[1]中的每个属性).
但第一种方法的表现要好很多倍!对于给定的json数据,代码[1]大约在1毫秒内运行,而代码[2]需要超过100毫秒!
更新
在James Newton-King(编写Json.NET :)的输入之后,还有另一种更优雅的方式来做到这一点[3]
projects = data["value"].ToObject<List<Project>>();