¿Cuál es la mejor manera de devolver errores de un servicio WCF de forma RESTful?
web-services error-handling (5)
Usar WCF de forma RESTful parece genial. Soy un gran admirador de las armas grandes, como la simplicidad y la flexibilidad, pero también me encanta la forma en que las Urls terminan buscando. Qué puedo decir, soy un programador.
La API simple para recuperar y editar recursos se combina con un conjunto casi igual de posibles respuestas de error, y no puedo evitar sentir que para mantener un enfoque RESTANTE "puro" puedo estar cortando mi nariz para despecho por la cara, o más específicamente, la nariz de los consumidores de mi servicio web. Podría estar equivocado, pero parece que no hay muchos códigos de error Http que pueda usar, y no hay formas de devolver un mensaje de error personalizado.
Para aclarar, estoy hablando de errores excepcionales adecuados y errores no esperados. Quiero comunicar un problema al usuario para ayudarlo a identificar lo que debe hacer para corregirlo.
Posibles opciones que estoy considerando ...
Solo use los códigos de error Http : parece que sería demasiado restrictivo en lo que puedo expresar y no me permitirá proporcionar un mensaje personalizado. Por favor, corríjame si estoy equivocado.
Siempre devuelva Http Success pero devuelva objetos personalizados de error : Obviamente, es el más flexible, pero ciertamente no el más RESTful.
Realmente apreciaría si alguien pudiera compartir alguna experiencia del mundo real de este problema en particular.
Actualizar
Gracias por la sugerencia de utilizar la propiedad StatusDescription
del objeto OutgoingWebResponseContext
. Al principio parecía ser algo que podía usar.
He llegado a la conclusión de que mi segunda opción anterior no es para mí. Quiero atenerme a lo que Http me puede dar.
Sin embargo, tengo problemas para hacerlo funcionar. Independientemente del valor que suministre para esta propiedad, no se devuelve en la respuesta.
Mi método de servicio se ve así
public MyType GetMyTypes(string criteria)
{
try
{
return GetMyTypes();
}
catch (Exception ex)
{
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = HttpStatusCode.Forbidden;
response.StatusDescription = "A Big fat error occurred";
return null;
}
}
Y aquí está el mensaje de respuesta sin procesar. No se menciona el mensaje personalizado ...
HTTP / 1.1 403 prohibido
Servidor: ASP.NET Development Server / 9.0.0.0
Fecha: mié, 07 ene 2009 14:01:20 GMT
Versión X-AspNet: 2.0.50727
Cache-Control: privado
Longitud del contenido: 0
Conexión: Cerrar
No es como si solo tuviera que acceder a la propiedad correcta en el cliente. La información simplemente no se envía a través del enlace.
¿Qué hace realmente esta propiedad StatusDescription
?
Actualizar
Nunca descubrí cómo configurar la propiedad StatusDescription. Terminé sin incluir ningún mensaje de error y recurriendo únicamente a los códigos de estado Http. He elegido exponer los puntos finales Soap y Restful para mis servicios, por lo que los clientes pueden elegir cuáles prefieren usar: los mensajes simples de Restful o los relativamente relativamente más ricos de Soap.
Agrego el código de error como se muestra arriba (en la descripción del estado) y en el cuerpo de la página devuelta en mis servicios REST como:
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = HttpStatusCode.Unauthorized;
response.StatusDescription = "You are not authorized.";
HttpContext.Current.Response.Write("You are not authorized.");
return null;
Con .net 4, lanza una WebFaultException<T>
(T errorDetail,
code)
HttpResponseCode
code)
Aquí establece su tipo de respuesta a otro tipo de objeto, lo que tiene sentido, y también establece el ResponseCode
que desea.
El errorDetail
debe ser serializable
Envíe el código de respuesta adecuado y puede proporcionar el mensaje de error personalizado en el cuerpo de la respuesta.
Esto puede ser un defecto. A partir del 22/09/2011, el equipo del producto está revisando el problema:
Vea este hilo para una pregunta similar.
En pocas palabras, creo que puede establecer el código de estado HTTP (a uno de los códigos de error) y proporcionar su mensaje personalizado en la propiedad StatusDescription :
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.Forbidden;
response.StatusDescription = "Custom";
No sé mucho sobre la prevalencia de esta técnica en el mundo real, lamentablemente.