Comment puis-je renvoyer un code d'état HTTP personnalisé à partir d'une méthode REST WCF?

88

Si quelque chose ne va pas dans un appel WCF REST, tel que la ressource demandée n'est pas trouvée, comment puis-je jouer avec le code de réponse HTTP (en le définissant sur quelque chose comme HTTP 404, par exemple) dans ma méthode OperationContract?

kgriffs
la source
ok toutes les réponses à cela supposent que le contrôle a été intégré à votre implémentation de service. et s'ils passent un uri totalement invalide? comment êtes-vous supposé fournir un 404 pour tous les coups inattendus de votre service?
Nathan Tregillus

Réponses:

111

Il y a un WebOperationContextauquel vous pouvez accéder et il a une OutgoingResponsepropriété de type OutgoingWebResponseContextqui a une StatusCodepropriété qui peut être définie.

WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
Eric Schoonover
la source
5
Cela fonctionne-t-il dans WCF Data Services - Service Operations? Je n'ai pas eu de chance, il semble que le StatusCode que j'ai défini soit dépassé par quelque chose d'autre. Donc, sur toutes les requêtes HTTP POST, je récupère 204 indépendamment du fait que je l'ai défini à 201, etc.
RyBolt
1
Ne fonctionne pas dans mon cas, le statut est écrasé. Lancer un WebFaultException, cependant, semble fonctionner.
Josh M.
73

Si vous devez renvoyer un corps de raison, jetez un œil à WebFaultException

Par exemple

throw new WebFaultException<string>("Bar wasn't Foo'd", HttpStatusCode.BadRequest );
Graeme Bradbury
la source
4
Je aime mieux que celui qui est accepté puisque nous n'utilisons le WebOperationContext.Current static
Noel Abrahams
gardez à l'esprit que cela n'est valable que depuis famework 4 msdn.microsoft.com/en-us/library/dd989924.aspx
sebagomez
hmm, dans .NET 4.5.1 cela ne définit pas le code de statut pour moi, je reçois toujours un 200. J'utilise jsonp, il appelle mon rappel (en javascript) et passe mon message et mon code de statut en tant que entier.
Shavais
4
Cela semble idéal pour tout ce qui est en dehors des codes 2XX, mais voudriez-vous lancer un WebFaultExceptionpour renvoyer un HttpStatusCode.Created?
écraser
23

Pour 404, il existe une méthode intégrée sur WebOperationContext.Current.OutgoingResponse appelée SetStatusAsNotFound (message sous forme de chaîne) qui définira le code d'état sur 404 et une description d'état en un seul appel.

Notez qu'il existe également SetStatusAsCreated (emplacement Uri) qui définira le code d'état sur 201 et l'en-tête d'emplacement avec un seul appel.

JarrettV
la source
Est-ce préférable à la méthode affichée dans la réponse acceptée?
écraser
2

Si vous souhaitez voir la description du statut dans l'en-tête, la méthode REST doit s'assurer de renvoyer null de la section Catch () comme ci-dessous:

catch (ArgumentException ex)
{
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError;
    WebOperationContext.Current.OutgoingResponse.StatusDescription = ex.Message;
    return null;
}
Hydtechie
la source
1
Cela n'a pas fonctionné pour moi non plus, j'obtiens toujours un 200. J'utilise WebHttpBinding avec crossDomainScriptAccessEnabled = "true" et un comportement de point final de webHttp avec un style de corps par défaut enveloppé et un format de réponse sortant par défaut de json. mais cela ne devrait pas avoir d'importance, n'est-ce pas?
Shavais
2

Vous pouvez également retourner un corps statuscode et la raison avec WebOperationContext de StatusCode et StatusDescription :

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