Restsharp: ResponseStatus est une erreur lorsque la réponse est 404 NotFound

Créé le 21 avr. 2016  ·  7Commentaires  ·  Source: restsharp/RestSharp

Utiliser RestClient.Execute(...) pour effectuer un GET qui aboutit à un 404.
La réponse IRestqui revient a ResponseStatus = Error.
- 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.

accepted IMPORTANT investigate

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 :

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

Tous les 7 commentaires

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.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

wojciechrak picture wojciechrak  ·  3Commentaires

tomgallard picture tomgallard  ·  6Commentaires

AlexanderSchoenfeld picture AlexanderSchoenfeld  ·  3Commentaires

qJake picture qJake  ·  7Commentaires

ChenJasonGit picture ChenJasonGit  ·  5Commentaires