3. WCF 异常处理
原文:http://www.rainsts.net/article.asp?id=430
WCF 将服务异常(Exception)转换成 SOAP faults,传递到客户端后再次转换成 Exception。只不过缺省情况下,我们很难从中获取有意义的信息。
<ServiceContract()> _
Public Interface IService1
<OperationContract()> _
Function GetData(ByVal value As Integer) As String
End Interface
Public Class Service1
Implements IService1
Public Function GetData(ByVal value As Integer) As String Implements IService1.GetData
Throw New Exception("发生错误。")
Return String.Format("You entered: {0}", value)
End Function
End Class
抛出来的异常信息:
接收对 http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/ 的 HTTP 响应时发生错误。这可能是由于服务终结点绑定未使用 HTTP 协议造成的。这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致。有关详细信息,请参阅服务器日志。
Server stack trace:
在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
不太好理解
当然,WCF 会提供一个包装异常类 FaultException 来帮助我们处理这些问题。
发生错误。
Server stack trace:
在 System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
在 System.Servi
这样就好理解多了,所以在服务端抛出异常时,使用FaultException 异常类。
另外,我们还可以通过 FaultContractAttribute 传递更详细的异常信息给客户端。
<ServiceContract()> _
Public Interface IService1
<OperationContract(), FaultContract(GetType(Fault))> _
Function GetData(ByVal value As Integer) As String
End Interface
Public Class Service1
Implements IService1
Public Function GetData(ByVal value As Integer) As String Implements IService1.GetData
Dim f As New Fault
f.ErrorCode = 200
f.Message = "发生错误"
Throw New FaultException(Of Fault)(f, f.Message)
Return String.Format("You entered: {0}", value)
End Function
End Class
<DataContract()> _
Public Class Fault
<DataMember()> _
Public ErrorCode As Integer
<DataMember()> _
Public Message As String = String.Empty
End Class
Public Interface IService1
<OperationContract(), FaultContract(GetType(Fault))> _
Function GetData(ByVal value As Integer) As String
End Interface
Public Class Service1
Implements IService1
Public Function GetData(ByVal value As Integer) As String Implements IService1.GetData
Dim f As New Fault
f.ErrorCode = 200
f.Message = "发生错误"
Throw New FaultException(Of Fault)(f, f.Message)
Return String.Format("You entered: {0}", value)
End Function
End Class
<DataContract()> _
Public Class Fault
<DataMember()> _
Public ErrorCode As Integer
<DataMember()> _
Public Message As String = String.Empty
End Class
客户端代码:
Sub Main()
Dim url As String = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/mex"
Dim host As New System.ServiceModel.ServiceHost(GetType(WcfServiceLibrary1.Service1))
host.AddServiceEndpoint(GetType(WcfServiceLibrary1.IService1), New System.ServiceModel.BasicHttpBinding(), url)
host.Open()
Console.WriteLine(host.State.ToString)
Dim c = New System.ServiceModel.ChannelFactory(Of WcfServiceLibrary1.IService1)(New System.ServiceModel.BasicHttpBinding, url)
Dim s As WcfServiceLibrary1.IService1 = c.CreateChannel
Try
Console.WriteLine(s.GetData(1))
Catch ex As System.ServiceModel.FaultException(Of WcfServiceLibrary1.Fault)
Console.WriteLine("错误代码:" & ex.Detail.ErrorCode)
Console.WriteLine("错误消息:" & ex.Detail.Message)
End Try
Console.ReadKey()
End Sub
Dim url As String = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/mex"
Dim host As New System.ServiceModel.ServiceHost(GetType(WcfServiceLibrary1.Service1))
host.AddServiceEndpoint(GetType(WcfServiceLibrary1.IService1), New System.ServiceModel.BasicHttpBinding(), url)
host.Open()
Console.WriteLine(host.State.ToString)
Dim c = New System.ServiceModel.ChannelFactory(Of WcfServiceLibrary1.IService1)(New System.ServiceModel.BasicHttpBinding, url)
Dim s As WcfServiceLibrary1.IService1 = c.CreateChannel
Try
Console.WriteLine(s.GetData(1))
Catch ex As System.ServiceModel.FaultException(Of WcfServiceLibrary1.Fault)
Console.WriteLine("错误代码:" & ex.Detail.ErrorCode)
Console.WriteLine("错误消息:" & ex.Detail.Message)
End Try
Console.ReadKey()
End Sub
这样异常信息,就可以传递到客户端了,不错!这一节,我基本上掌握了!