Pergunta

Eu tenho um serviço de descanso consumido por um cliente .NET WCF.

Quando um erro é encontrado, o serviço restante retorna uma solicitação ruim HTTP 400 com o corpo de resposta que contém detalhes serializados JSON.

Se eu executar a solicitação usando Fiddler, JavaScript ou diretamente de C#, posso acessar facilmente o corpo de resposta quando ocorrer um erro.

No entanto, estou usando um WCF ChannelFactory com 6 interfaces bastante complexas. A exceção lançada por este proxy é sempre um ProtocolException, sem detalhes úteis.

Existe alguma maneira de obter o corpo de resposta quando recebo esse erro?


Atualizar

Sei que existem várias maneiras diferentes de fazer isso usando .NET e que existem outras maneiras de obter a resposta de erro. Eles são úteis para saber, mas não respondem a essa pergunta.

Os serviços restantes que estamos usando mudam e quando eles fazem as interfaces complexas são atualizadas. Usando o ChannelFactory Com as novas interfaces significa que obteremos exceções de tempo de compilação (em vez de executar tempo) e facilitaremos a manutenção e a atualização do código.

Existe alguma maneira de obter o corpo de resposta para um status HTTP de erro ao usar canais WCF?

Foi útil?

Solução

Não use o ChannelFactory :-) Sério. Por que você criaria uma interface de repouso e, em seguida, usaria o proxy do cliente WCF. Qual é o benefício de usar o serviço restante? Por que não usar apenas WshttpBinding? Com a classe HTTPClient no kit de partida REST, você pode fazer solicitações HTTP padrão e, em seguida, desfilizar a resposta usando o DataContractSerializer.

Por exemplo

var httpClient = new HttpClient();
var content = httpClient.Get("http://example.org/customer/45").Content;
var customer = content.ReadAsDataContract<Customer>()

Outras dicas

Você pode recuperar os detalhes da exceção como abaixo:

                Exception innerException = exception.InnerException;
                WebException webException = innerException as WebException;
                HttpWebResponse response = webException.Response as HttpWebResponse;
                string statusDescription = response.StatusDescription;
                HttpStatusCode statusCode = response.StatusCode;

o InnerException do ProtocolException será uma WebException. Você pode obter o HttpWebResponse a partir disso e ligue GetResponseStream para ler o corpo de resposta real. (Lembre -se de procurar o início do fluxo antes de ler).

var webException = (WebException) protocolException.InnerException;
var response = (HttpWebResponse) webException.Response;
var responseStream = response.GetResponseStream()
responseStream.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(responseStream);
var responseContent = reader.ReadToEnd();

Você poderia tentar jogar um WebProtocolexception do serviço. Dessa forma, os detalhes do erro devem ser incluídos no corpo da resposta HTTP. Dê uma olhada neste artigo:

Manipulação de erros eficaz com WCF e REST

Meus dois centavos é que o WCF é bom em expor a mesma classe usando muitas ligações diferentes. Ao se comunicar com C#, use uma ligação de sabão boa em informações de exceção. Se você precisar usar a encadernação do estilo REST, poderá usar um WebRequest simples para ligar para o Serviço e usar o Serializer JSON para desserializar os resultados. Isso também fornecerá acesso direto ao código de resposta.

A abordagem descrita pelo usuário653761 funciona para mim; Depois de ter acesso ao HttpWebResponse objeto eu posso usar o DataContractSerializer aula como esta:

var serializer = new DataContractSerializer(typeof(MyDataContractType));
var deserialized = 
    (serializer.ReadObject(httpWebResponse.GetResponseStream()) as MyDataContractType);

// ...

Eu acho que isso funcionaria para qualquer coisa que o WCF possa serializar se você usar o serializador certo, ainda não testou o desempenho (ainda).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top