使用 WebFaultException 的 WCF 错误管理 - 错误的 HttpStatusCode
WCF error management using WebFaultException - Wrong HttpStatusCode
我已经实现了一个简单的 Web 服务,我想 return 根据调用方法中发生的错误适当的 Http 状态错误代码。
我目前正在使用带有 Visual Studio 2019 的 .NET Framework 4.7.2 和 Visual Studio 中内置的 IIS Express 10 进行测试。我正在使用 Chrome 的 Boomerang 扩展来调用该服务。
我实现了一个带有名称的 FindPerson
方法。如果找不到这个人,或者找到一个以上的人,我想return一个"Not Found"响应(404)。
我已经实现了一个简单的 ServiceError
class,我用它来抛出一个 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 class:
<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
这是我得到的回复。就像我说的,细节是正确的...但是 Http 状态错误代码是 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>
编辑:
我找到了解决问题的方法,但这只让我意识到我需要找到更好的解决方案。
解决方案涉及实现一个名为 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 消费测试应用程序中测试调用该方法时,我没有看到服务错误详细信息。我收到一般性 404 错误,其中包含一条一般性错误消息,指出 "the endpoint couldn't be reached" 而不是 "the person wasn't found"。这会让任何通过使用 .NET 实现的消费应用程序调用服务的人感到困惑
我不确定这是我未来服务中错误管理的最佳解决方案。
我愿意接受有关 .NET Web 服务错误管理最佳实践的任何建议。
谢谢
我找到了我最初问题的解决方案:将 OutGoingResponse.StatusCode
设置为我用于 WebFaultException
的相同状态代码
解决方案涉及实现一个名为 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), status)
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 消费测试应用程序中测试调用该方法时,我没有看到服务错误详细信息。我收到一般性 404 错误,其中包含一条一般性错误消息,指出 "the endpoint couldn't be reached" 而不是 "the person wasn't found"。这会让通过使用 .NET 实现的消费应用程序调用服务的任何人感到困惑。
因此,虽然这是对我原来 question/problem 的回答,但它似乎不适合整个项目。祝其他遇到同样事情的人好运。
我已经实现了一个简单的 Web 服务,我想 return 根据调用方法中发生的错误适当的 Http 状态错误代码。
我目前正在使用带有 Visual Studio 2019 的 .NET Framework 4.7.2 和 Visual Studio 中内置的 IIS Express 10 进行测试。我正在使用 Chrome 的 Boomerang 扩展来调用该服务。
我实现了一个带有名称的 FindPerson
方法。如果找不到这个人,或者找到一个以上的人,我想return一个"Not Found"响应(404)。
我已经实现了一个简单的 ServiceError
class,我用它来抛出一个 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 class:
<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
这是我得到的回复。就像我说的,细节是正确的...但是 Http 状态错误代码是 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>
编辑: 我找到了解决问题的方法,但这只让我意识到我需要找到更好的解决方案。
解决方案涉及实现一个名为 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 消费测试应用程序中测试调用该方法时,我没有看到服务错误详细信息。我收到一般性 404 错误,其中包含一条一般性错误消息,指出 "the endpoint couldn't be reached" 而不是 "the person wasn't found"。这会让任何通过使用 .NET 实现的消费应用程序调用服务的人感到困惑
我不确定这是我未来服务中错误管理的最佳解决方案。
我愿意接受有关 .NET Web 服务错误管理最佳实践的任何建议。
谢谢
我找到了我最初问题的解决方案:将 OutGoingResponse.StatusCode
设置为我用于 WebFaultException
解决方案涉及实现一个名为 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), status)
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 消费测试应用程序中测试调用该方法时,我没有看到服务错误详细信息。我收到一般性 404 错误,其中包含一条一般性错误消息,指出 "the endpoint couldn't be reached" 而不是 "the person wasn't found"。这会让通过使用 .NET 实现的消费应用程序调用服务的任何人感到困惑。
因此,虽然这是对我原来 question/problem 的回答,但它似乎不适合整个项目。祝其他遇到同样事情的人好运。