RestSharp无法反序列化JSON对象列表,始终为Null。

33

我在使用RestSharp将返回内容反序列化为我的类时遇到了问题。 从我所有的搜索中看来,我正在正确地执行此操作。 我宁愿使用RestSharp的反序列化器,而不是不得不退回到另一个包(如Newstonsoft的Json.NET)。

我所做的是向GoToWebinar发出API请求,以获取所有计划的网络研讨会列表:

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);

如您所见,我想获取一个“RootObject”对象的列表(如下所示)。 我收到了以下JSON响应:

[
   {
      "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"
   }
]

我使用http://json2csharp.com根据以上JSON结果创建了以下对象:

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; }
}

问题在于response2.Data总是空的。由于某些原因,反序列化失败了,我不知道为什么。我的目标是能够使用foreach循环来遍历结果:
foreach(RootObject r in response2.Data)
{
    lblGoToWebinar.Text += r.webinarKey.ToString() + ", ";
}

有什么想法造成反序列化失败?

2
你能否调试并查看response2对象以查看其原始值?你应该使用调试器检查是否存在错误。 - agarcian
1
谢谢@agarcian!根据您的建议,我开始搜索一些内部错误,并在下面的答案中找到了解决方法。 - Easton James Harvey
3个回答

92

基于@agarcian上面的建议,我搜索了一下这个错误:

restsharp数据在根层级无效。第1行,第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的文档可以更清晰地引用此内容。希望这能帮助其他人!


2
指定 Method.GET 是多余的,不是吗?(这是默认的方法类型) - ashes999
3
根据讨论串,推荐的方法是:client.AddHandler("text/plain", new JsonDeserializer()),这确实应该写进文档中。 - Rowan
4
@Rowan这种方法对我没用(RestSharp的最新版本)。OnBeforeDeserialization技巧确实有效。不过,我认为既然我指定了RequestFormat = DataFormat.Json,它应该自动识别。 - pbz
@EastonJamesHarvey:感谢您指向该线程。添加text/plain处理程序可能无法正常工作,因为服务器没有响应该Content-Type。它对我有用,所以我添加了一个答案,但奇怪的是RestSharp文档没有讨论这个问题。 - Nick Westgate
1
真是糟糕透了。为什么我总是不得不来StackOverflow,只是为了提醒自己要学习已经掌握的信息? - Dan Narsavage

4

参加晚了:你需要找到你获取的响应的确切的Content-Type。服务器不一定会响应您请求头中的任何内容类型。对于 Google 的 API,我得到了一个 text/plain 响应,所以这个来自群组的建议对我有用。

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来指定响应类型,那么这样做也更加整洁。

3

我遇到了相同的问题,但是上面的答案都没有帮助到我。

这是我的响应类:

public class SomeResponse
{
    public string string1;
    public string string2;
}

问题出在人为的错误上——我忘记包括 get/set 访问器。我很少使用 C#,所以忘记了需要它们。
public class SomeResponse
{
    public string string1 { get; set; }
    public string string2 { get; set; }
}

希望这对某个人有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接