Pregunta

Tengo un servicio REST consumida por un cliente WCF .Net.

Cuando se detecta un error del servicio REST devuelve un HTTP 400 Bad Request con el cuerpo de la respuesta JSON serializado que contiene detalles.

Si ejecuto la solicitud utilizando Fiddler, Javascript o directamente desde C # Puedo acceder fácilmente al cuerpo de la respuesta cuando se produce un error.

Sin embargo, estoy usando un ChannelFactory WCF con 6 interfaces de bastante complejos. La excepción lanzada por esta representación es siempre un ProtocolException, sin detalles útiles.

¿Hay alguna manera de obtener el cuerpo de la respuesta cuando me sale este error?


Actualizar

Me da cuenta de que hay un montón de diferentes maneras de hacer esto utilizando .Net y que hay otras maneras de conseguir la respuesta de error. Son útiles para saber, pero no responden a esta pregunta.

Los servicios REST que estamos utilizando va a cambiar y cuando lo hacen las interfaces complejas se actualizan. Utilizando el ChannelFactory con los nuevos medios interfaces que nos pondremos tiempo de compilación (en lugar de tiempo de ejecución) y hacer que estas excepciones mucho más fácil de mantener y actualizar el código.

¿Hay alguna manera de obtener el cuerpo de la respuesta para un estado HTTP de error cuando usa los canales WCF?

¿Fue útil?

Solución

No utilice ChannelFactory :-) En serio. ¿Por qué se crea una interfaz REST y luego usar el proxy de cliente WCF. ¿Cuál es la ventaja de utilizar el servicio REST? ¿Por qué no sólo tiene que utilizar wsHttpBinding? Con la clase HttpClient del kit de arranque RESTO puede hacer peticiones HTTP estándar y luego deserializar la respuesta utilizando DataContractSerializer.

por ejemplo.

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

Otros consejos

puede recuperar el detalle excepción de la siguiente manera:

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

El InnerException del ProtocolException será un WebException. Usted puede obtener el HttpWebResponse de eso y llamar GetResponseStream para leer el cuerpo de la respuesta real. (Recuerde que debe buscar al comienzo de la corriente antes de la lectura).

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

Usted podría intentar tirar un WebProtocolException en el servicio. De esta manera los detalles del error se debe incluir en el cuerpo de la respuesta HTTP. Echar un vistazo a este artículo:

Control de errores eficaz con WCF y REST

Mis dos centavos es que WCF es bueno en la exposición de la misma clase utilizando muchas ediciones diferentes. Cuando se comunica con C #, utilice un jabón de unión que es bueno en la información de excepción. Si tiene que usar la unión del estilo REST, se puede utilizar un WebRequest sencilla para llamar al servicio y utilizar el serializador JSON para deserializar los resultados. Esto también le dará acceso directo al código de respuesta.

El enfoque descrito por user653761 funciona para mí; después de tener acceso al objeto HttpWebResponse puedo utilizar la clase DataContractSerializer como esto:

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

// ...

supongo que esto funcionaría para cualquier cosa que WCF puede serializar si se utiliza el serializador derecha, no lo hizo prueba de rendimiento (todavía).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top