Restsharp: ResponseStatus é um erro quando a resposta é 404 NotFound

Criado em 21 abr. 2016  ·  7Comentários  ·  Fonte: restsharp/RestSharp

Use RestClient.Execute(...) para realizar um GET que resulte em um 404.
O IRestResponseque volta tem ResponseStatus = Erro.
- A propriedade ErrorException possui a mensagem "Cadeia JSON inválida".
- A propriedade de dados response = null.

Execute a mesma solicitação com o (não genérico) RestClient.Execute (...).
O IRestResponse tem ResponseStatus = Complete

Parece que não está conseguindo desserializar a resposta no modelo digitado (TResult).
Neste recurso API específico retorna um corpo de conteúdo de "" (caractere de espaço único), não tenho certeza se deveria ser um corpo completamente vazio.

Eu esperava que o ResponseStatus em ambos os casos fosse Concluído - a solicitação foi bem-sucedida, onde não havia erros de transporte.

accepted IMPORTANT investigate

Comentários muito úteis

Por "não genérico", quero dizer o método Execute no RestClient que não aceita um parâmetro genérico:

IRestResponse Execute(IRestRequest request);

contra:

IRestResponse<T> Execute<T>(IRestRequest request) where T : new();

Se ajudar, acabei resolvendo o problema escrevendo um método de extensão em IRestResponse que usa Json.NET para desserializar a propriedade Content:

public static TResult Content<TResult>(this IRestResponse response)
{
    return JsonConvert.DeserializeObject<TResult>(response.Content);
}

Eu poderia então usar o método Execute "não genérico" para fazer minha solicitação e obter uma resposta digitada com meu método de extensão:

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

Realizando as mesmas etapas com o Execute "genérico":

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

Todos 7 comentários

Eu configurei um aplicativo Windows Forms para testar. Você poderia fornecer mais detalhes sobre esse problema? Não tenho certeza do que você quer dizer com "não genérico"

Por "não genérico", quero dizer o método Execute no RestClient que não aceita um parâmetro genérico:

IRestResponse Execute(IRestRequest request);

contra:

IRestResponse<T> Execute<T>(IRestRequest request) where T : new();

Se ajudar, acabei resolvendo o problema escrevendo um método de extensão em IRestResponse que usa Json.NET para desserializar a propriedade Content:

public static TResult Content<TResult>(this IRestResponse response)
{
    return JsonConvert.DeserializeObject<TResult>(response.Content);
}

Eu poderia então usar o método Execute "não genérico" para fazer minha solicitação e obter uma resposta digitada com meu método de extensão:

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

Realizando as mesmas etapas com o Execute "genérico":

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

Estou tendo o mesmo problema com a v105.2.3, então mudei minhas chamadas Execute <> para Execute e usei a sugestão acima, que resolveu o problema.

O problema parece ser devido ao conteúdo do servidor para uma resposta HTTP 500 ser um pedaço de HTML, que não pode ser desserializado no meu tipo usando o serializador JSON e, portanto, estou supondo que ResponseStatus está definido como Erro como o a desserialização falhou.

A documentação atual sugere que o ResponseStatus é definido apenas para erros relacionados à rede / conectividade e não para erros de desserialização.

Pelo que vale a pena, minha proposta seria que a propriedade Data lance uma exceção se a desserialização falhar, em vez de alterar o ResponseStatus de Concluído para Erro (embora isso possa representar uma alteração significativa para aqueles que esperam que funcione como funciona atualmente).

Ainda aberto? Isso vai a algum lugar? Parece que já deve ser abordado ou comentado e fechado agora.

Eu acho que deveria ser consertado. A sugestão de @simonob parece muito razoável. Muitos aplicativos retornam respostas ruins que não podemos desserializar, isso é bastante normal.

Ok, isso de fato é por design. Eu adicionei uma opção para retornar Concluído quando a desserialização falhar. Para a compatibilidade com versões anteriores, devo manter o comportamento atual como está, mas se você definir RestClient.FailOnDeserializationError como falso na próxima versão, você o classificará.

Por curiosidade, qual foi o motivo para seguir esse comportamento?
Para mim, parece que o comportamento mais lógico no caso em que uma solicitação é concluída com êxito e recebe um código de status do servidor, mas não consegue ser desserializada localmente, seria ter IsSuccessful falso e ResponseStatus = Concluído.

Do jeito que está atualmente, não há, pelo que eu posso dizer, nenhuma maneira de dizer olhando para qualquer uma dessas propriedades, se a solicitação falhou em obter uma resposta do servidor ou foi concluída com êxito, mas falhou ao desserializar. Eles basicamente parecem indicar a mesma coisa, tornando um deles redundante.

Esta página foi útil?
0 / 5 - 0 avaliações