Как я могу вернуть собственный код состояния HTTP из метода REST WCF?


88

Если что-то пойдет не так в вызове WCF REST, например, запрошенный ресурс не найден, как я могу поиграть с кодом ответа HTTP (например, установив для него что-то вроде HTTP 404) в моем методе OperationContract?


Хорошо, все ответы на этот вопрос предполагают, что контроль вошел в реализацию вашей службы. что, если они передадут совершенно неверный URI? как вы предполагаете предоставить 404 для всех неожиданных обращений к вашей службе?
Nathan Tregillus

Ответы:


111

Существует объект, к WebOperationContextкоторому вы можете получить доступ, и у него есть OutgoingResponseсвойство типа, у OutgoingWebResponseContextкоторого есть StatusCodeсвойство, которое можно установить.

WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;

5
Работает ли это внутри WCF Data Services - Service Operations? Мне не повезло, кажется, что установленный мной StatusCode превзошел что-то еще. Итак, на все запросы HTTP POST я возвращаю 204, независимо от того, что я установил его на 201 и т. Д.
RyBolt

1
В моем случае не работает, статус перезаписывается. Однако бросок WebFaultException, похоже, работает.
Джош М.

73

Если вам нужно вернуть тело причины, посмотрите WebFaultException

Например

throw new WebFaultException<string>("Bar wasn't Foo'd", HttpStatusCode.BadRequest );

4
Мне это нравится больше, чем принятый, поскольку мы не используем статический WebOperationContext.Current
Ноэль Абрахамс

имейте в виду, что это действительно только с тех пор, как famework 4 msdn.microsoft.com/en-us/library/dd989924.aspx
sebagomez

хм, в .NET 4.5.1 это не устанавливает для меня код состояния, я все еще получаю 200. Я использую jsonp, он вызывает мой обратный вызов (в javascript) и передает мое сообщение и мой код состояния как целое число.
Шаваис

4
Кажется, это отлично подходит для чего-либо, кроме кодов 2XX, но вы бы бросили a, WebFaultExceptionчтобы вернуть HttpStatusCode.Created?
Crush

23

Для 404 существует встроенный метод в WebOperationContext.Current.OutgoingResponse, называемый SetStatusAsNotFound (строковое сообщение) , который установит код состояния на 404 и описание состояния одним вызовом.

Обратите внимание, что есть также SetStatusAsCreated (местоположение Uri) , который установит код состояния на 201 и заголовок местоположения с помощью одного вызова.


Это предпочтительнее метода, указанного в принятом ответе?
Crush

2

Если вы хотите видеть описание статуса в заголовке, метод REST должен убедиться, что возвращает null из раздела Catch (), как показано ниже:

catch (ArgumentException ex)
{
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError;
    WebOperationContext.Current.OutgoingResponse.StatusDescription = ex.Message;
    return null;
}

1
У меня это тоже не сработало, я все еще получаю 200. Я использую WebHttpBinding с crossDomainScriptAccessEnabled = "true" и поведение конечной точки webHttp со стилем тела по умолчанию обернутым и форматом исходящего ответа по умолчанию json .. но это не имеет значения, не так ли?
Шаваис

2

Вы также можете вернуть StatusCode и причину тела с WebOperationContext «s StatusCode и StatusDescription :

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


0

У меня это не сработало для служб данных WCF. Вместо этого вы можете использовать DataServiceException в случае Data Services. Нашел следующий пост полезным. http://social.msdn.microsoft.com/Forums/en/adodotnetdataservices/thread/f0cbab98-fcd7-4248-af81-5f74b019d8de


У меня это тоже не работает, я просто получаю 400 Bad Request, без другой полезной информации и без тела ответа.
Шаваис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.