Joe*_*Joe 69 c# json task-parallel-library asp.net-mvc-4 dotnet-httpclient
我正在尝试反序列化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"
},
...
]
Run Code Online (Sandbox Code Playgroud)
指数行动:
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();
...
}
Run Code Online (Sandbox Code Playgroud)
工作和工作类:
[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; }
}
Run Code Online (Sandbox Code Playgroud)
当我设置断点jsonTask.Wait();并检查jsonTask状态是Faulted.InnerException是"Type ProjectName.Jobs不是集合".
我开始使用没有JsonArray属性的Jobs类型和作为数组的Job(Job [])并得到了这个错误.
public class Jobs { public Job[] JSON; }
+ InnerException {"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ProjectName.Models.Jobs' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\n
To fix this error either change the JSON to a JSON object (e.g. {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface
(e.g. 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}
Run Code Online (Sandbox Code Playgroud)
我如何使用.NET 4.0任务模式处理此站点的JSON?await async在使用.NET 4.5中的模式之前,我想让它工作.
答案更新:
这是使用.NET 4.5异步等待模式和brumScouse的答案的示例.
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);
}
Run Code Online (Sandbox Code Playgroud)
您需要引入System.Threading.Tasks命名空间.
注意:没有.ReadAsString可用的方法,.Content这就是我使用该.ReadAsStringAsync方法的原因.
bru*_*use 89
您可以尝试使用Json2csharp.com网站之类的东西,而不是手工制作模型.粘贴在示例JSON响应中,越大越好,然后拉入生成的类.这至少会带走一些移动部件,在csharp中为您提供JSON的形状,为序列化器提供更简单的时间,您不必添加属性.
只需使其工作,然后修改您的类名,以符合您的命名约定,并在以后添加属性.
编辑:好的,有点搞乱我已经成功地将结果反序列化为一个工作列表(我使用Json2csharp.com为我创建类)
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; }
}
Run Code Online (Sandbox Code Playgroud)
并编辑您的代码:
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();
Run Code Online (Sandbox Code Playgroud)
这意味着你可以摆脱你的包含对象.值得注意的是,这不是与任务相关的问题,而是反序列化问题.
编辑2:
有一种方法可以获取JSON对象并在Visual Studio中生成类.只需复制选择的JSON,然后编辑>选择性粘贴>将JSON粘贴为类.这里有一整页专门介绍:
http://blog.codeinside.eu/2014/09/08/Visual-Studio-2013-Paste-Special-JSON-And-Xml/
Vee*_*asi 17
var response = taskwithresponse.Result;
var jsonString = response.ReadAsAsync<List<Job>>().Result;
Run Code Online (Sandbox Code Playgroud)
返回类型取决于服务器,有时响应确实是一个 JSON 数组,但作为文本/纯文本发送
在请求中设置接受头应该得到正确的类型:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Run Code Online (Sandbox Code Playgroud)
然后可以将其序列化为 JSON 列表或数组。感谢@svick 的评论,这让我很好奇它应该可以工作。
我在没有配置接受标头的情况下得到的异常是 System.Net.Http.UnsupportedMediaTypeException。
以下代码更清晰,应该可以工作(未经测试,但在我的情况下有效):
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 = await response.Content.ReadAsAsync<List<Job>>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
153507 次 |
| 最近记录: |