¿Cómo puedo devolver un código de estado HTTP personalizado desde un método WCF REST?

88

Si algo sale mal en una llamada WCF REST, como por ejemplo, no se encuentra el recurso solicitado, ¿cómo puedo jugar con el código de respuesta HTTP (configurándolo en algo como HTTP 404, por ejemplo) en mi método OperationContract?

kgriffs
fuente
ok, todas las respuestas a este control asumido se incluyeron en la implementación de su servicio. ¿Qué pasa si pasan algún uri totalmente inválido? ¿Cómo se supone que debe proporcionar un 404 para todos los accesos inesperados a su servicio?
Nathan Tregillus

Respuestas:

111

Hay un al WebOperationContextque puede acceder y tiene una OutgoingResponsepropiedad de tipo OutgoingWebResponseContextque tiene una StatusCodepropiedad que se puede configurar.

WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
Eric Schoonover
fuente
5
¿Funciona esto dentro de WCF Data Services - Service Operations? No he tenido suerte, parece que el StatusCode que configuré es superado por otra cosa. Entonces, en todas las solicitudes HTTP POST, obtengo 204 independientemente de que lo haya configurado en 201, etc.
RyBolt
1
No funciona en mi caso, el estado se sobrescribe. Lanzar un WebFaultException, sin embargo, parece funcionar.
Josh M.
73

Si necesita devolver un cuerpo de motivo, eche un vistazo a WebFaultException

Por ejemplo

throw new WebFaultException<string>("Bar wasn't Foo'd", HttpStatusCode.BadRequest );
Graeme Bradbury
fuente
4
Me gusta esto más que el aceptado ya que no estamos usando el WebOperationContext estático.Current
Noel Abrahams
tenga en cuenta que esto solo es válido desde famework 4 msdn.microsoft.com/en-us/library/dd989924.aspx
sebagomez
hmm, en .NET 4.5.1 esto no está configurando el código de estado para mí, todavía obtengo un 200. Estoy usando jsonp, está llamando a mi devolución de llamada (en javascript) y pasando mi mensaje y mi código de estado como un entero.
Shavais
4
Esto parece genial para cualquier cosa fuera de los códigos 2XX, pero ¿arrojaría un WebFaultExceptionpara devolver un HttpStatusCode.Created?
aplastar el
23

Para 404 hay un método integrado en WebOperationContext.Current.OutgoingResponse llamado SetStatusAsNotFound (mensaje de cadena) que establecerá el código de estado en 404 y una descripción de estado con una llamada.

Tenga en cuenta que también hay SetStatusAsCreated (ubicación de Uri) que establecerá el código de estado en 201 y el encabezado de ubicación con una llamada.

JarrettV
fuente
¿Se prefiere este método al que se muestra en la respuesta aceptada?
aplastar el
2

Si desea ver la descripción del estado en el encabezado, el método REST debe asegurarse de devolver nulo desde la sección Catch () como se muestra a continuación:

catch (ArgumentException ex)
{
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError;
    WebOperationContext.Current.OutgoingResponse.StatusDescription = ex.Message;
    return null;
}
Hydtechie
fuente
1
Esto tampoco funcionó para mí, todavía obtengo un 200. Estoy usando WebHttpBinding con crossDomainScriptAccessEnabled = "true" y un comportamiento de punto final de webHttp con un estilo de cuerpo predeterminado de envuelto y un formato de respuesta saliente predeterminado de json .. pero eso no debería importar, ¿verdad?
Shavais
2

También puede volver un cuerpo statuscode y razonar con WebOperationContext 's StatusCode y statusDescription :

WebOperationContext context = WebOperationContext.Current;
context.OutgoingResponse.StatusCode = HttpStatusCode.OK;
context.OutgoingResponse.StatusDescription = "Your Message";
eitzo
fuente