2010-03-07 89 views
1

在我的Silverlight应用程序中,我使用Visual Studio生成的客户端(添加服务引用...)异步调用Web服务。
我的代码如下所示:Silverlight和WCF:处理'WCF down'异常/ WCF连接检查

ServiceClient serviceClient = new ServiceClient(); 
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted); 
serviceClient.GetServerTimeAsync(); 

void serviceClient_GetServerTimeCompleted(object sender, GetServerTimeCompletedEventArgs e) 
{ 
     // do nothing atm 
} 

一切工作正常,只要该服务启动并运行,但是当服务没有运行,我得到:

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) 

“在 操作期间发生异常,导致结果无效。 检查InnerException以获取异常 的详细信息。“

的InnerException

“发生错误,而试图 做出请求URI 的‘http://’,这可能是 由于试图在一个交叉访问服务 没有适当的 跨域策略或者 策略不适用于SOAP 服务您可能需要联系 服务的所有者以发布 跨域策略文件,它允许发送与SOAP相关的HTTP标头 。通过使用Web 服务代理中的内部类型,而不使用 InternalsVisibleToAttribute属性,也可能导致此错误 。 请参阅内部异常 更多的细节。”

这是有道理的,我在这种情况下得到一个例外,但我无法弄清楚是怎么赶上我的客户端代码中的异常。是有一个标准的方法来做到这一点?如果我理解这是如何工作的,当我的代码调用生成的代码时,它会产生另一个线程,它实际调用Web服务并等待响应。该线程和生成的异常代码我的呼叫代码(见上)或我的回拨方式都没有机会看到异常情况

谢谢

Christian

回答

1

有很多原因不使用Visual Studio中的“添加服务引用”功能。这里有一篇关于这个问题的好文章(和长篇),以及how to use WCF creating your clients。我现在正在自己解决这些问题。

有关“添加服务引用”的问题包括可下载客户端.XAP文件中的代码膨胀,难以维护生成的代码,当服务器地址和端口在客户端配置中被硬编码时难以进行登台或发送代码文件(也嵌入在.XAP中)等等。构建您自己的客户端还将使您更好地管理客户端代码中的异常。

有一些权衡;您需要将数据合同类移植到Silverlight环境。 (你不能只添加一个引用到服务器端的.NET程序集,它不起作用。)上面链接的网站在re-using assemblies in Silverlight上有一篇很好的文章,但处理这个问题最简单的方法是从您的Silverlight项目中添加指向服务器端类的链接。 (在Silverlight项目中,右键单击并添加 - >添加现有项目...并找到要包含的项目,但不单击添加按钮,单击其旁边的向下箭头并单击“添加为链接“)。注意其他引用和使用引用服务器端类的语句;您可能需要进行条件编译,以便您的数据合同类在客户端项目中干净地编译。

总的来说,它确实看起来像一个更清洁的方式,尤其是对于可能使用大量服务合同和数据合同的大型项目,或者需要将Silverlight项目作为商业应用程序的一部分运输人们的服务器。对于可测试性来说,它也应该更加清洁,特别是对于集成和分期测试。

+0

感谢,我将深入探讨这些网页,但我不想改变我交谈的WCF的方式。使用添加服务引用非常“方便”,我没有时间atm .. – 2010-03-09 05:07:30

0

我以前遇到过这个问题 - 您需要在您的ServiceClient设置代码中添加异常处理代码。我通常检查以下的CommunicationExceptionTimeoutException异常,并EndpointNotFoundException,并告诉他们的东西被破坏用户提供适当的对话框:

ServiceClient serviceClient; 
try 
{ 
    serviceClient = new ServiceClient(); 
    serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted); 
    serviceClient.GetServerTimeAsync(); 
} 
catch (EndpointNotFoundException ex) 
{ 
    // log exception 
    // show error dialog 
} 

注:这不会处理asnchronous期间遇到的错误方法回调 - 它需要它自己的(类似的)异常处理。

+0

Bermo,你有一个示例显示了如何包装ServiceClient安装程序代码?我的意思是,你使用服务参考? 谢谢 基督徒 – 2010-03-09 05:08:29

+0

更新后添加一些示例代码。 – Bermo 2010-03-09 07:09:48

0

其实你必须把crossdomainaccesspolicy.xml放在IIS默认的网站根目录下。 您复制下面给出的xml内容并保存在ClinetAccespolicy.xml的名称中,然后放在IIS默认网站根文件夹中。