Десериализуйте JSON в массив или список с помощью HTTPClient.ReadAsAsync using.NET 4.0 шаблон задачи
я пытаюсь десериализовать JSON, возвращенный из http://api.usa.gov/jobs/search.json?query=nursing+jobs
Использование шаблона задачи .NET 4.0. Он возвращает этот JSON ('Load JSON data'@ 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"
},
...
]
Действие Index:
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
статус
Неисправный. InnerException - это " тип ProjectName.Jobs это не коллекция."
я начал с типа заданий без JsonArray атрибут и задания в виде массива (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.rn
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.rn
Path '', line 1, position 1."} System.Exception {Newtonsoft.Json.JsonSerializationException}
как бы я обработал JSON этого сайта с шаблоном задач .NET 4.0? Я хотел бы получить эту работу, прежде чем перейти к await async
шаблон в .NET 4.5.
ОТВЕТ ОБНОВЛЕНИЕ:
вот пример с использованием .Объем 4.5 использованием ключевых слов async await со ответ 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);
}
вам нужно будет принести в System.Threading.Tasks
пространство имен.
Примечание: нет .ReadAsString
метод доступен на .Content
вот почему я использовал .ReadAsStringAsync
метод.
3 ответа:
вместо того, чтобы наручники ваши модели попробуйте использовать что-то вроде Json2csharp.com сайт. Вставьте в пример ответ JSON, чем полнее, тем лучше, а затем вытащите результирующие сгенерированные классы. Это, по крайней мере, убирает некоторые движущиеся части, даст вам форму JSON в csharp, давая сериализатору более легкое время, и вам не нужно добавлять атрибуты.
просто заставить его работать, а потом внести изменения в имена классов, чтобы соответствовать вашим именованием соглашения, и добавить атрибуты позже.
изменить: ОК после небольшой возни я успешно десериализовал результат в список заданий (я использовал 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; } }
и редактирование кода:
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. Просто скопируйте данные в JSON и затем правка> Специальная вставка > вставить JSON в качестве классов. Целая страница посвящена этому здесь:
http://blog.codeinside.eu/2014/09/08/Visual-Studio-2013-Paste-Special-JSON-And-Xml/
тип возврата зависит от сервера, иногда ответ действительно является массивом JSON, но отправляется как text / plain
установка заголовков accept в запросе должна получить правильный тип:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
, который затем может быть сериализован в список JSON или массива. Спасибо за комментарий от @svick, который заставил меня любопытно, что он должен работать.
исключение, которое я получил без настройки заголовков accept, было Системы.Чистая.Протоколу 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 = response.Content.ReadAsAsync<List<Job>>();