Utiliser RestClient.Execute
La réponse IRest
- La propriété ErrorException a le message "Chaîne JSON non valide".
- La réponse de la propriété Data = null.
Effectuez la même requête avec le RestClient.Execute(...) (non générique).
L'IRestResponse a ResponseStatus = Complete
Il semble qu'il ne parvient pas à désérialiser la réponse dans le modèle typé (TResult).
Dans cette ressource d'API particulière, il renvoie un corps de contenu " " (caractère à espace unique), sans savoir s'il doit s'agir d'un corps complètement vide.
Je me serais attendu à ce que le ResponseStatus dans les deux cas soit terminé - la demande a réussi, là où aucune erreur de transport.
J'ai configuré une application Windows Forms pour tester. Pourriez-vous fournir plus de détails sur ce problème? Je ne sais pas ce que vous entendez par "non générique"
Par "non générique", j'entendais la méthode Execute sur RestClient qui ne prend pas de paramètre générique :
IRestResponse Execute(IRestRequest request);
contre:
IRestResponse<T> Execute<T>(IRestRequest request) where T : new();
Si cela peut aider, j'ai fini par contourner le problème en écrivant une méthode d'extension sur IRestResponse qui utilise Json.NET pour désérialiser la propriété Content :
public static TResult Content<TResult>(this IRestResponse response)
{
return JsonConvert.DeserializeObject<TResult>(response.Content);
}
Je pourrais alors utiliser la méthode Execute "non générique" pour faire ma requête et obtenir une réponse tapée avec ma méthode d'extension :
var resp = client.Execute(new RestRequest("some/resource"));
if (resp.ResponseStatus != ResponseStatus.Completed) { // Check whether request completed
//Handle error
}
if (resp.StatusCode == HttStatusCode.NotFound) { // Check for 404
//Handle 404
}
var result = resp.Content<SomeResult>();
Exécuter les mêmes étapes avec l'Execute "générique":
var resp = client.Execute<SomeResult>(new RestRequest("some/resource"));
if (resp.ResponseStatus != ResponseStatus.Completed) {
//This is reached even for 404 - I presume because of a failure during deserialization
}
//Handling 404 here isn't possible be cause it appears the request did not complete...
if (resp.StatusCode == HttStatusCode.NotFound) {
//Handle 404
}
var result = resp.Data; // Data is null
J'ai le même problème avec la v105.2.3, j'ai donc changé mes appels Execute<> en Execute et utilisé la suggestion ci-dessus qui a résolu le problème.
Le problème semble être dû au contenu du serveur pour une réponse HTTP 500 étant un morceau de HTML, qui ne peut pas être désérialisé dans mon type à l'aide du sérialiseur JSON et donc je suppose que le ResponseStatus est défini sur Erreur comme le la désérialisation a échoué.
La documentation actuelle suggère que le ResponseStatus n'est défini que pour les erreurs liées au réseau/connectivité, et non pour les erreurs de désérialisation.
Pour ce que ça vaut, ma proposition serait que la propriété Data lève une exception si la désérialisation échoue, plutôt que de changer le ResponseStatus de Completed à Error (bien que cela puisse représenter un changement décisif pour ceux qui s'attendent à ce qu'il fonctionne comme il le fait actuellement).
Toujours ouvert? Est-ce que ça va quelque part ? On dirait qu'il devrait être traité ou commenté et fermé maintenant.
Je pense que ça devrait être corrigé. La suggestion de @simonob semble très raisonnable. De nombreuses applications renvoient des réponses de merde que nous ne pouvons pas désérialiser, c'est tout à fait normal.
Ok, c'est en fait par conception. J'ai ajouté une option pour retourner Terminé lorsque la désérialisation échoue. Pour la compatibilité descendante, je dois conserver le comportement actuel tel quel, mais si vous définissez RestClient.FailOnDeserializationError
sur false dans la prochaine version, vous le trierez.
Par curiosité, quelle était la raison de ce comportement ?
Pour moi, il me semble que le comportement le plus logique dans le cas où une demande se termine avec succès et reçoit un code d'état du serveur, mais ne parvient pas à être désérialisé localement, serait d'avoir IsSuccessful sur false et ResponseStatus = Completed.
Dans l'état actuel des choses, il n'y a, pour autant que je sache, aucun moyen de savoir, en regardant l'une ou l'autre de ces propriétés, si la demande n'a pas obtenu de réponse du serveur ou s'est terminée avec succès mais n'a pas réussi à se désérialiser. Ils semblent fondamentalement tous les deux indiquer la même chose, rendant l'un d'eux redondant.
Commentaire le plus utile
Par "non générique", j'entendais la méthode Execute sur RestClient qui ne prend pas de paramètre générique :
IRestResponse Execute(IRestRequest request);
contre:
IRestResponse<T> Execute<T>(IRestRequest request) where T : new();
Si cela peut aider, j'ai fini par contourner le problème en écrivant une méthode d'extension sur IRestResponse qui utilise Json.NET pour désérialiser la propriété Content :
Je pourrais alors utiliser la méthode Execute "non générique" pour faire ma requête et obtenir une réponse tapée avec ma méthode d'extension :
Exécuter les mêmes étapes avec l'Execute "générique":