Вопрос по asp.net, rest, http, .net, c# – RestSharp не десериализует JSON Object List, всегда Null

28

У меня возникла проблема с десериализацией RestSharp возвращаемого контента в мои классы. Из всех моих поисков кажется, что я делаю это правильно. Я бы предпочел использовать десериализатор RestSharp, чем прибегать к другому пакету, такому как Json.NET от Newstonsoft.

Я делаю запрос API к GoToWebinar для всего списка запланированных вебинаров:

<code>var client = new RestClient(string.Format("https://api.citrixonline.com/G2W/rest/organizers/{0}/upcomingWebinars", "300000000000239000"));
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "OAuth oauth_token=" + System.Configuration.ConfigurationManager.AppSettings["GoToWebinar"]);
var response2 = client.Execute<List<RootObject>>(request);
</code>

Как вы видите, я хотел бы получить список объектов «RootObject». (как показано ниже). Я получаю следующий ответ JSON в response2.Content:

<code>[
   {
      "webinarKey":678470607,
      "subject":"Easton's Wild Rice Cooking Demo",
      "description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
      "organizerKey":300000000000239551,
      "times":[{"startTime":"2012-05-09T15:00:00Z","endTime":"2012-05-09T16:00:00Z"}],
      "timeZone":"America/Denver"
   },
   {
      "webinarKey":690772063,
      "subject":"Easton's Match Making Service",
      "description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
      "organizerKey":300000000000239551,
      "times":[{"startTime":"2012-05-09T15:00:00Z","endTime":"2012-05-09T16:00:00Z"}],
      "timeZone":"America/Denver"
   }
]
</code>

Я создал следующие объекты, используяhttp://json2csharp.com используя результаты JSON выше:

<code>public class RootObject
{
    public int webinarKey { get; set; }
    public string subject { get; set; }
    public string description { get; set; }
    public long organizerKey { get; set; }
    public List<Time> times { get; set; }
    public string timeZone { get; set; }
}

public class Time
{
    public string startTime { get; set; }
    public string endTime { get; set; }
}
</code>

Проблема в response2.Data всегда Null. По какой-то причине десериализация не удалась, и я не знаю почему. Моя цель - использовать цикл foreach для итерации результатов:

<code>foreach(RootObject r in response2.Data)
{
    lblGoToWebinar.Text += r.webinarKey.ToString() + ", ";
}
</code>

Любые идеи о том, почему десериализация терпит неудачу?

рад, что это сработало !!! agarcian
Спасибо @agarcian! Основываясь на вашем предложении, я начал искать некоторые из внутренних ошибок и понял, как это видно из моего ответа ниже. Easton James Harvey
Можете ли вы отладить и посмотреть наresponse2 объект, чтобы увидеть, что является необработанным значением? Вы должны увидеть, если есть ошибка с отладчиком. agarcian

Ваш Ответ

2   ответа
77

restsharp Data at the root level is invalid. Line 1, position 1.

и нашел этот форум:http://groups.google.com/group/restsharp/browse_thread/thread/ff28ddd9cd3dde4b

По сути, я ошибался, предполагая, что client.Execute собирался автоматически определять тип возвращаемого содержимого. Нужно установить эксплозивность:

var request = new RestRequest(Method.GET);
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };

Это может быть процитировано более четко в документации RestSharp. Надеюсь, это поможет кому-то еще!

ОпределениеMethod.GET избыточно, не так ли? (Это тип метода по умолчанию)
В соответствии с темой рекомендуемый подход:client.AddHandler("text/plain", new JsonDeserializer())это действительно должно быть в документации
@EastonJamesHarvey: спасибо за указатель на ветку. Добавление обработчика текста / обычного текста, вероятно, не сработало для вас, потому что сервер не ответил с этим Content-Type. Это сработало для меня, поэтому я добавил ответ, но странно, что документы RestSharp не обсуждают это.
@ ashes999, согласился. Easton James Harvey
@Rowan Этот подход не работает для меня (последняя версия RestSharp). Уловка OnBeforeDeserialization работает. Однако, это должно автоматически понять это, так как я указываю RequestFormat = DataFormat.Json, imo.
1

actual Content-Type ответа, который вы получили. Сервер не обязательно отвечает ни одним из типов контента из заголовка Accept вашего запроса. Для API Google я получил текстовый / простой ответ, так что этосовет от группы работал на меня.

public T Execute<T>(string url, RestRequest request) where T : new()
{
    var client = new RestClient();
    // tell RestSharp to decode JSON for APIs that return "Content-Type: text/plain"
    client.AddHandler("text/plain", new JsonDeserializer());
    ...

Также лучше, если это можно сделать в одном месте, например, с помощью общего метода Execute, описанного выше, вместо того, чтобы форсировать тип ответа с помощью OnBeforeDeserialization, где бы ни создавался каждый запрос.

Похожие вопросы