WCF Web服务调用 – 要捕获的exception?

我有一个调用外部Web服务的程序,我想向用户提供一个友好的对话框,例如服务器关闭,有人切断电缆等。假设以下代码

try { client.MyWebService() } catch(? ex) { // display friendly dialog explaining what went wrong } 

我应该在代码中用什么例外代替问号? 当一切工作顺利并且我无法控制外部部件时,很难真正测试这样的情况,因此有些见解会受到赞赏。

谢谢!

要做的第一件事就是利用代理上的.Fululted事件,你可以像这样连接:

 ((ICommunicationObject)client).Faulted += new EventHandler(client_Faulted); 

client_Faulted事件处理程序中,您可以尝试重新连接,或转移到备份服务器,或禁用UI,记录错误或在那里显示消息。

在try-catch中包装每个调用显然仍然是一个好习惯,但是.Faulted事件可以让你甚至更早地处理大多数通道问题。

至于exception本身,您可以让您的服务抛出一个FaultException ,它会通过您提供的详细信息传递回客户端。 请参阅此博客文章中使用的示例。

如果通道本身发生故障,您将不会获得FaultException(FaultException是服务器将其自身内部故障传达给客户端的一种方式)。

对于通道故障,您可能会收到CommunicationExceptionTimeoutException

最后,看一下Codeplex上的这个项目 ,用于生成exception处理WCF代理。 它可以为您提供更灵活的处理故障的方法。

提供尽可能详细的细节并不是客户的真正工作。 您真正需要在客户端提供的最大金额与您在exception中获得的金额一样多。

 var userName = "bob"; try { client.MyWebService(userName); } catch(Exception ex) { //Maybe we know WellKnownExceptions and can provide Foo advice: if (ex is WellKnownException) { Console.WriteLine("WellKnownException encountered, do Foo to fix Bar."); } //otherwise, this is the best you can do: Console.WriteLine(string.Format( "MyWebService call failed for {0}. Details: {1}", userName, ex)); } 

我问同样的问题,因为我必须在我的客户端应用程序上对Web服务调用实现一些exception处理,所以我最终在这里。 虽然这是一个老问题,但我想给我两分钱,稍微更新一下。

C. Lawrence Wenham给出的答案已经非常好,并指出了一些有趣的信息,尽管博客链接已被破坏,Codeplex现已存档。

我发现这些文章很有价值:

发送和接收故障
https://docs.microsoft.com/en-us/dotnet/framework/wcf/sending-and-receiving-faults

预期的例外情况
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/expected-exceptions

MichèleLerouxBustamante(显然是exception处理WCF代理生成器 CodePlex项目的创建者)的这篇文章也非常有用:

优雅的exception处理代理解决方案
http://www.itprotoday.com/microsoft-visual-studio/elegant-exception-handling-proxy-solution

我还在研究这个主题,但我想我会使用Michèle的很多想法。 我只是有点担心使用reflection调用Web服务的方法,但我想知道这是否会对这种操作产生任何影响,这本身就很慢。

只是在这里明确回答最初提出的问题,即可以针对Web服务调用测试的exception:

 string errorMessage = null; // A class derived from System.ServiceModel.ClientBase. MyWebService wcfClient = new MyWebService(); try { wcfClient.Open(); wcfClient.MyWebServiceMethod(); } catch (TimeoutException timeEx) { // The service operation timed out. errorMessage = timeEx.Message; } catch (FaultException declaredFaultEx) { // An error on the service, transmitted via declared SOAP // fault (specified in the contract for an operation). errorMessage = declaredFaultEx.Detail.Message; } catch (FaultException unknownFaultEx) { // An error on the service, transmitted via undeclared SOAP // fault (not specified in the contract for an operation). errorMessage = unknownFaultEx.Message; } catch (CommunicationException commEx) { // A communication error in either the service or client application. errorMessage = commEx.Message; } finally { if (wcfClient.State == CommunicationState.Faulted) wcfClient.Abort(); else wcfClient.Close(); } 

正如文章所述,捕获exception的顺序很重要,因为FaultException派生自FaultException ,而FaultException派生自CommunicationException