2012-04-25 21 views
28

Tengo un problema con RestSharp que deserializa el contenido devuelto en mis clases. De toda mi búsqueda parece que estoy haciendo esto correctamente. Prefiero usar el deserializador de RestSharp que tener que recurrir a otro paquete como el Json.NET de Newstonsoft.RestSharp no deserializa la lista de objetos JSON, siempre nulo

Lo que estoy haciendo está haciendo una solicitud del API para GoToWebinar para toda lista de webinarios programados:

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

Como ves me gustaría obtener una lista de objeto 'RootObject' (como se muestra a continuación). Estoy recibiendo la siguiente respuesta JSON en 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" 
    } 
] 

que crearon los siguientes objetos usando http://json2csharp.com utilizando los resultados JSON anterior:

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

El problema es response2.Data es siempre nulo. Por alguna razón, la deserialización falló y no sé por qué. Mi objetivo es ser capaz de utilizar un bucle foreach para iterar a través de los resultados:

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

alguna idea de por qué el deserialización está fallando?

¡Gracias de antemano!

+2

¿Puedes depurar y mirar el objeto 'response2' para ver cuál es el valor bruto? Debería ver si hay un error con el depurador. – agarcian

+1

¡Gracias @agarcian! En función de su sugerencia, comencé a buscar algunos de los errores internos y lo descubrí como visto en mi respuesta a continuación. –

+0

contento de que funcionó !!! – agarcian

Respuesta

71

Sobre la base de la sugerencia de @ agarcian anterior, busqué en Google el error:

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

y encontramos este foro: http://groups.google.com/group/restsharp/browse_thread/thread/ff28ddd9cd3dde4b

Básicamente, yo era un error suponer que client.Execute se va a poder para detectar automáticamente el tipo de contenido devuelto. Hay que establecer explícitamente:

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

Esto podría ser citado con mayor claridad en la documentación del RestSharp. ¡Espero que esto ayude a alguien más a salir!

+2

Especificar 'Method.GET' es redundante, ¿no es así? (Ese es el tipo de método predeterminado) – ashes999

+0

@ ashes999, acordado. –

+3

De acuerdo con el hilo el enfoque recomendado es: 'client.AddHandler (" text/plain ", new JsonDeserializer())', esto realmente debería estar en la documentación – Rowan

1

Tarde a la fiesta: Debería encontrar el real Content-Type de la respuesta que estaba obteniendo. El servidor no responde necesariamente con ninguno de los tipos de contenido del encabezado Aceptar de su solicitud. Para las API de Google recibí una respuesta de texto/simple, por lo que este advice from the group funcionó para mí.

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

También es más ordenado si se puede hacer en un solo lugar, como la compartida Ejecutar método anterior, en lugar de forzar el tipo de respuesta con OnBeforeDeserialization donde se crea cada solicitud.

Cuestiones relacionadas