2012-07-16 62 views
10

Tengo el siguiente código:manejando agraciado un objeto JSON vacío en RestSharp

public void GetJson() 
{ 
    RestRequest request = new RestRequest(Method.GET); 

    var data = Execute<Dictionary<string, MyObject>>(request); 
} 

public T Execute<T>(RestRequest request) where T : new() 
{ 
    RestClient client = new RestClient(baseUrl); 
    client.AddHandler("text/plain", new JsonDeserializer()); 

    var response = client.Execute<T>(request); 

    return response.Data; 
} 

El problema es que a veces la respuesta será una matriz JSON vacío []. Y cuando ejecuto este código recibo la siguiente excepción: No se puede convertir el objeto de tipo 'RestSharp.JsonArray' para escribir 'System.Collections.Generic.IDictionary`2 [System.String, System.Object]'.

¿Hay alguna manera de manejar esto con elegancia?

+0

¿Tiene alguna posibilidad de cambiar la respuesta del servidor? Debería haberle devuelto un objeto vacío {} en lugar de un conjunto vacío []. Los dos no son compatibles incluso en JSON. –

+0

Puedo pensar en hacks simples pero eso es todo. – evanmcdonnal

+0

@Thomas: ¿Alguien tiene más pensamientos sobre esto? Encuentra alguna respuesta? Lo estoy obteniendo de la API de Facebook. En una determinada llamada, cuando envía datos no válidos, devuelve un diccionario que le dice lo que estaba mal y por qué. De lo contrario, devuelve una matriz json vacía '[]'. Muy molesto. Ideas? – xan

Respuesta

0

Nunca he necesitado la línea client.AddHandler, así que no estoy seguro de que la necesite. Pruebe esto para su método Execute, sin embargo:

public T Execute<T>(RestRequest request) where T : class, new() 
{ 
    RestClient client = new RestClient(baseUrl); 
    client.AddHandler("text/plain", new JsonDeserializer()); 

    try 
    { 
     var response = client.Execute<T>(request); 
     return response.Data; 
    } 
    catch (Exception ex) 
    { 
     // This is ugly, but if you don't want to bury any errors except when trying to deserialize an empty array to a dictionary... 
     if (ex is InvalidCastException && typeof(T) == typeof(Dictionary<string, MyObject>)) 
     { 
      // Log the exception? 
      return new T(); 
     } 

     throw; 
    } 
} 
+0

No estoy seguro de que esto ayude a responder las preguntas; sí, posiblemente sea una buena alternativa para evitar que la excepción se propague, pero el problema es que la API es inconstante. ¿Alguna idea sobre cómo configurar RestSharp para lidiar con esto, o cómo solucionar esto manualmente? – xan

+0

@xan - Edité mi respuesta un poco. Esta respuesta es una forma de solucionar manualmente el problema presentado por el PO. Creo que el problema es un error/deficiencia en RestSharp y no conozco una forma de configurar RestSharp para manejarlo. – jfren484

4

Trabajé alrededor de un problema similar yo de la siguiente manera. Había intentado usar deserializadores personalizados (ya que estaba deserializando un objeto complejo) pero al final la siguiente era mucho más simple, ya que solo se aplicaba a una de las muchas clases de solicitudes que estaba haciendo.

request.OnBeforeDeserialization = (x => 
{ 
    x.Content = x.Content.Replace("[]", "{}"); 
}); 

donde yo estaba construyendo el objeto de solicitud para esta solicitud en particular, que utiliza la propiedad OnBeforeDeserialization para establecer una devolución de llamada que sustituye a la incorrecta [] con {}. Esto funciona para mí porque sé que los datos que obtengo en el resto de x.Content nunca contendrán [] excepto en este caso especializado, incluso en los valores.

Esto podría ayudar a otra persona, pero definitivamente debe usarse con cuidado.

+0

Gracias xan! mi código es [ligeramente diferente] (https://gist.github.com/koreus7/b1be123762aea29b6362) pero lo probé con RestSharp 105.0.1.0 y funcionó. Estoy un poco sorprendido de que RestSharp no lo resuelva. ¿Crees que vale la pena informar sobre GitGub? – koreus737

+0

Me gusta la adición de 'OnBeforeDeserialization' porque significa que solo tengo que hacer esto una vez para todas mis solicitudes en mi fábrica de solicitudes. Este error me volvió loco durante más de un día. Resultó que simplemente no habíamos llegado a la situación en la que nuestra solicitud no arrojó resultados en la matriz, por lo que no habíamos visto el error antes. Se siente un poco * hacky y sucio, pero no parecía haber otra forma mejor de manejar esto y no queríamos tener que cambiar el deserializador. –

Cuestiones relacionadas