繁体   English   中英

WCF Web服务调用 - 要捕获哪个异常?

[英]WCF web service call - which exception(s) to catch?

我有一个调用外部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事件可以让你更早地处理大多数通道问题。

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

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

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

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

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

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

而这篇文章从米歇尔·勒鲁布斯塔曼特异常处理WCF代理生成 CodePlex项目的明显的创建者)是非常insighful也:

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

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

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

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<ExceptionDetail> 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();
}

正如文章所述,捕获异常的顺序很重要,因为FaultException<TDetail>派生自FaultException ,而FaultException派生自CommunicationException

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

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));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM