Как я могу вернуть собственный код состояния 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 и заголовок местоположения с помощью одного вызова.

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

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

catch (ArgumentException ex)
{
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError;
    WebOperationContext.Current.OutgoingResponse.StatusDescription = ex.Message;
    return null;
}
Hydtechie
источник
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";
Eitzo
источник
0

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

ТолькоМахеш
источник
У меня это тоже не работает, я просто получаю 400 Bad Request, без другой полезной информации и без тела ответа.
Шаваис