web-dev-qa-db-fra.com

RestSharp ne désérialise pas la liste d'objets JSON, toujours Null

J'ai un problème avec RestSharp qui désérialise le contenu de retour dans mes classes. De toutes mes recherches, il semble que je fais cela correctement. Je préférerais de loin utiliser le désérialiseur de RestSharp plutôt que de recourir à un autre package comme Json.NET de Newstonsoft.

Ce que je fais, c'est de faire une demande d'API à GoToWebinar pour toute la liste des webinaires programmés:

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

Comme vous le voyez, je voudrais obtenir une liste d'objets 'RootObject' (comme indiqué ci-dessous). Je reçois la réponse JSON suivante dans response2.Content:

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

J'ai créé les objets suivants en utilisant http://json2csharp.com en utilisant les résultats JSON ci-dessus:

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

Le problème est response2.Data est toujours Null. Pour une raison quelconque, la désérialisation a échoué et je ne sais pas pourquoi. Mon objectif est de pouvoir utiliser une boucle foreach pour parcourir les résultats:

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

Des idées sur la raison de l'échec de la désérialisation?

31

Sur la base de la suggestion de @ agarcian ci-dessus, j'ai googlé l'erreur:

restsharp Les données au niveau racine ne sont pas valides. Ligne 1, position 1.

et a trouvé ce forum: http://groups.google.com/group/restsharp/browse_thread/thread/ff28ddd9cd3dde4b

Fondamentalement, j'avais tort de supposer que le client. Execute allait pouvoir détecter automatiquement le type de contenu renvoyé. Il doit être défini explicitement:

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

Cela pourrait être cité plus clairement dans la documentation de RestSharp. J'espère que cela aidera quelqu'un d'autre!

80

Tard dans la soirée: vous devez trouver le réel type de contenu de la réponse que vous obtenez. Le serveur ne répond pas nécessairement avec l'un des types de contenu de l'en-tête Accepter de votre demande. Pour les API de Google, j'ai reçu un texte/une réponse simple, donc cela conseil du groupe a fonctionné pour moi.

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

C'est aussi plus ordonné si cela peut être fait à un endroit tel que la méthode d'exécution partagée ci-dessus, plutôt que de forcer le type de réponse avec OnBeforeDeserialization partout où chaque demande est créée.

1
Nick Westgate