使用.NET 4.0任务模式将JSON反序列化为使用HTTPClient .ReadAsAsync的数组或列表

我试图反序列化从http://api.usa.gov/jobs/search.json?query=nursing+jobs使用.NET 4.0任务模式返回的JSON。 它返回这个JSON('加载JSON数据'@ http://jsonviewer.stack.hu/ )。

 [ { "id": "usajobs:353400300", "position_title": "Nurse", "organization_name": "Indian Health Service", "rate_interval_code": "PA", "minimum": 42492, "maximum": 61171, "start_date": "2013-10-01", "end_date": "2014-09-30", "locations": [ "Gallup, NM" ], "url": "https://www.usajobs.gov/GetJob/ViewDetails/353400300" }, { "id": "usajobs:359509200", "position_title": "Nurse", "organization_name": "Indian Health Service", "rate_interval_code": "PA", "minimum": 42913, "maximum": 61775, "start_date": "2014-01-16", "end_date": "2014-12-31", "locations": [ "Gallup, NM" ], "url": "https://www.usajobs.gov/GetJob/ViewDetails/359509200" }, ... ] 

索引操作:

  public class HomeController : Controller { public ActionResult Index() { Jobs model = null; var client = new HttpClient(); var task = client.GetAsync("http://api.usa.gov/jobs/search.json?query=nursing+jobs") .ContinueWith((taskwithresponse) => { var response = taskwithresponse.Result; var jsonTask = response.Content.ReadAsAsync<Jobs>(); jsonTask.Wait(); model = jsonTask.Result; }); task.Wait(); ... } 

工作和工作类:

  [JsonArray] public class Jobs { public List<Job> JSON; } public class Job { [JsonProperty("organization_name")] public string Organization { get; set; } [JsonProperty("position_title")] public string Title { get; set; } } 

当我设置jsonTask.Wait(); 并检查jsonTask的状态是jsonTask 。 InnerException是“typesProjectName.Jobs不是集合”。

我开始与乔布斯types没有JsonArray属性和作为一个数组(作业[]),并得到了这个错误。

  public class Jobs { public Job[] JSON; } + InnerException {"Cannot deserialize the current JSON array (eg [1,2,3]) into type 'ProjectName.Models.Jobs' because the type requires a JSON object (eg {\"name\":\"value\"}) to deserialize correctly.\r\n To fix this error either change the JSON to a JSON object (eg {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface (eg ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.\r\n Path '', line 1, position 1."} System.Exception {Newtonsoft.Json.JsonSerializationException} 

如何处理这个网站的JSON与.NET 4.0任务模式? 我想在.NET 4.5中await asyncawait async模式之前,先完成这个工作。

答案更新:

下面是一个使用brumScouse的答案使用.NET 4.5asynchronous等待模式的示例。

  public async Task<ActionResult>Index() { List<Job> model = null; var client = newHttpClient(); // .NET 4.5 async await pattern var task = await client.GetAsync(http://api.usa.gov/jobs/search.json?query=nursing+jobs); var jsonString = await task.Content.ReadAsStringAsync(); model = JsonConvert.DeserializeObject<List<Job>>(jsonString); returnView(model); } 

您将需要引入System.Threading.Tasks命名空间。
注意:.ReadAsString上没有.ReadAsString方法,这就是我使用.ReadAsStringAsync方法的原因。

不要手动模型尝试使用像Json2csharp.com网站的东西。 粘贴在一个示例JSON响应中,越完善,然后拉入生成的生成的类。 这至less会带走一些运动的部件,会让你在csharp中获得JSON的形状,给串行器更容易的时间,而且你不需要添加属性。

只要让它工作,然后修改你的类名称,以符合你的命名约定,并在稍后添加属性。

编辑:好了后,有点搞乱我已经成功地将结果反序列化到作业列表(我用Json2csharp.com为我创build类)

 public class Job { public string id { get; set; } public string position_title { get; set; } public string organization_name { get; set; } public string rate_interval_code { get; set; } public int minimum { get; set; } public int maximum { get; set; } public string start_date { get; set; } public string end_date { get; set; } public List<string> locations { get; set; } public string url { get; set; } } 

并编辑你的代码:

  List<Job> model = null; var client = new HttpClient(); var task = client.GetAsync("http://api.usa.gov/jobs/search.json?query=nursing+jobs") .ContinueWith((taskwithresponse) => { var response = taskwithresponse.Result; var jsonString = response.Content.ReadAsStringAsync(); jsonString.Wait(); model = JsonConvert.DeserializeObject<List<Job>>(jsonString.Result); }); task.Wait(); 

这意味着你可以摆脱你的包含对象。 值得注意的是,这不是一个与任务有关的问题,而是一个反序列化问题。

编辑2:

有一种方法可以获取JSON对象并在Visual Studio中生成类。 只需复制select的JSON,然后编辑>select性粘贴>将JSON粘贴为类。 整个页面专门在这里:

http://blog.codeinside.eu/2014/09/08/Visual-Studio-2013-Paste-Special-JSON-And-Xml/

 var response = taskwithresponse.Result; var jsonString = response.ReadAsAsync<List<Job>>().Result; 

返回types取决于服务器,有时响应确实是一个JSON数组,但是以text / plain方式发送

在请求中设置接受标题应该得到正确的types:

 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

然后可以将其序列化为JSON列表或数组。 感谢@svick的评论,这让我好奇它应该工作。

我没有configuration接受头的exception是System.Net.Http.UnsupportedMediaTypeException。

下面的代码更清洁,应该工作(未经testing,但在我的情况下):

  var client = new HttpClient(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await client.GetAsync("http://api.usa.gov/jobs/search.json?query=nursing+jobs"); var model = response.Content.ReadAsAsync<List<Job>>();