Я реализовал простой веб-сервис и хочу вернуть соответствующие коды ошибок статуса Http в зависимости от ошибки, возникшей в вызываемом методе.
Я использую. NET framework 4.7.2 с Visual Studio 2019 и IIS Express 10 встроены в Visual Studio для тестирования на данный момент. Я использую расширение Бумеранг для Chrome для вызова службы.
Я реализовал метод FindPerson
, который принимает имя. Если человек не найден или найдено более одного человека, я хочу вернуть ответ «Не найдено» (404).
Я реализовал простой класс ServiceError
, который я использую для броска WebFaultException
вместе с кодом ошибки Not Found. Когда я выбрасываю WebFaultException
, соответствующая реакция на ошибку отправляется потребителю (я вижу подробности проблемы) , но статус http 500 (внутренняя ошибка службы) вместо ошибки 404, которую я использовал ( и ожидается получение)
Вот мой простой FindPerson
метод:
Private Function FindPerson(ByVal name As String) As Person Implements MyService.FindPerson
Dim foundPerson As Person = Nothing
Dim people = GetPeople(name)
Select Case people.Count
Case Is > 1
Throw New WebFaultException(Of ServiceError)(New ServiceError("More than 1 person found with the name provided.", ""), HttpStatusCode.NotFound)
Case Is = 0
Throw New WebFaultException(Of ServiceError)(New ServiceError("No Person with the name provided was found.", ""), HttpStatusCode.NotFound)
Case Else
foundPerson = people(0)
End Select
Return foundPerson
End Function
Вот мой класс ServiceError:
<DataContract>
Public Class ServiceError
<DataMember>
Public Property ErrorInfo As String
<DataMember>
Public Property ErrorDetails As String
Public Sub New(ByVal info As String, ByVal details As String)
Me.ErrorInfo = info
Me.ErrorDetails = details
End Sub
Public Sub New()
End Sub
End Class
Это ответ I получить. Как я уже сказал, детали верны ... но Http Status Error Code - это 500 вместо 404:
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value
xmlns:a="http://schemas.microsoft.com/2009/WebFault">a:NotFound
</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">Not Found</s:Text>
</s:Reason>
<s:Detail>
<ServiceError
xmlns="http://schemas.datacontract.org/2004/07/My_Web_Service"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ErrorDetails/>
<ErrorInfo>No Person with the name provided was found.</ErrorInfo>
</ServiceError>
</s:Detail>
</s:Fault>
</s:Body>
</s:Envelope>
Edit: Я нашел решение своей проблемы, но оно имеет только заставил меня осознать, что мне нужно найти лучшее решение.
Решение заключалось в реализации метода под названием RaiseWebException
, который устанавливает код состояния исходящего ответа в состояние, также установленное в исключении WebFaultException:
Private Sub RaiseWebException(ByVal status As HttpStatusCode, ByVal info As String, ByVal details As String)
WebOperationContext.Current.OutgoingResponse.StatusCode = status
Throw New WebFaultException(Of ServiceError)(New ServiceError(info, details), HttpStatusCode.NotFound)
End Sub
Я вызвал метод, когда не смог найти свою личность:
Private Function FindPerson(ByVal name As String) As Person Implements MyService.FindPerson
Dim foundPerson As Person = Nothing
Dim people = GetPeople(name)
Select Case people.Count
Case Is > 1
RaiseWebException(HttpStatusCode.NotFound, "More than 1 person found with the name provided.", "")
Case Is = 0
RaiseWebException(HttpStatusCode.NotFound, "Person with the name provided was found.", "")
Case Else
foundPerson = people(0)
End Select
Return foundPerson
End Function
Это хорошо работает при вызове метода из браузера с помощью Boomerang; однако, когда я тестирую вызов метода в тестируемом приложении, использующем vb. net, я не вижу сведений об ошибке службы. Я получаю сообщение об ошибке c 404 с сообщением об ошибке c, в котором говорится, что «конечная точка не может быть достигнута» вместо «человек не найден». Это может сбить с толку любого, кто вызывает службу через приложение-потребитель, реализованное с помощью. NET
Я не уверен, что это лучшее решение для управления ошибками в моем сервисе в будущем.
Я открыт для любых предложений по передовым методам управления ошибками в. NET веб-сервисах.
Спасибо