WP7:无法在对 WCF 服务的异步调用中捕获 FaultException

Posted

技术标签:

【中文标题】WP7:无法在对 WCF 服务的异步调用中捕获 FaultException【英文标题】:WP7: Unable to catch FaultException in asynchronous calls to WCF service 【发布时间】:2012-04-03 19:49:09 【问题描述】:

我目前正在开发一个 Windows Phone 7 应用程序,该应用程序调用我也控制的 WCF Web 服务。该服务提供了一个操作,当给定用户的登录名和密码时返回当前用户的帐户信息:

[ServiceContract]
public interface IWindowsPhoneService

    [OperationContract]
    [FaultContract(typeof(AuthenticationFault))]
    WsAccountInfo GetAccountInfo(string iamLogin, string password);

当然,始终存在身份验证失败的可能性,我想将该信息传达给 WP7 应用程序。在这种情况下我可以简单地返回 null,但我想传达身份验证失败的原因(即登录未知、密码错误、帐户被阻止……)。

这是我对上述操作的实现(出于测试目的,它所做的只是抛出一个异常):

public WsAccountInfo GetAccountInfo(string iamLogin, string password)

    AuthenticationFault fault = new AuthenticationFault();
    throw new FaultException<AuthenticationFault>(fault);

现在,如果我在我的 WP7 应用程序中调用此操作,如下所示:

Global.Proxy.GetAccountInfoCompleted += new EventHandler<RemoteService.GetAccountInfoCompletedEventArgs>(Proxy_GetAccountInfoCompleted);
Global.Proxy.GetAccountInfoAsync(txbLogin.Text, txbPassword.Password);

void Proxy_GetAccountInfoCompleted(object sender, RemoteService.GetAccountInfoCompletedEventArgs e)

    if (e.Error != null)
    
        MessageBox.Show(e.Error.Message);
        return;
    

调试器在 Reference.cs 中中断,说 FaultException'1 未处理,这里:

public PhoneApp.RemoteService.WsAccountInfo EndGetAccountInfo(System.IAsyncResult result) 
      object[] _args = new object[0];
      PhoneApp.RemoteService.WsAccountInfo _result = ((PhoneApp.RemoteService.WsAccountInfo)(base.EndInvoke("GetAccountInfo", _args, result)));
      return _result;

开始更新 1

当按下 F5 时,异常冒泡到:

public PhoneApp.RemoteService.WsAccountInfo Result 
  get 
    base.RaiseExceptionIfNecessary();   // <-- here
    return ((PhoneApp.RemoteService.WsAccountInfo)(this.results[0]));
  

然后到:

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)

    if (System.Diagnostics.Debugger.IsAttached)
    
        // An unhandled exception has occurred; break into the debugger
        System.Diagnostics.Debugger.Break();
    

之后,应用程序终止(有或没有调试器)。

结束更新 1

现在,我很想在我的代码中捕获异常,但我从来没有机会,因为我的 Completed 处理程序永远不会到达。

基于此站点上的类似问题,我已经尝试了以下方法:

重新添加服务引用 --> 没有变化 从头开始重新创建一个非常简单的 WCF 服务 --> 同样的问题 在没有调试器的情况下启动应用程序,以防止应用程序闯入调试器 --> 好吧,它不会中断,但也没有捕获到异常,应用程序只是退出 告诉 VS 2010 不要在 FaultExceptions 上中断(调试 > 选项)--> 没有任何效果 将我应用程序中的每一行都包装在 try ... catch (FaultException) 甚至 catch (Exception) --> 从未调用过。

开始更新 2

我真正想要实现的是以下之一:

理想情况下,到达 GetAccountInfoCompleted(...) 并能够通过 GetAccountInfoCompletedEventArgs.Error 属性检索异常,或者

能够通过 try/catch 子句捕获异常

结束更新 2

如果您有任何可以帮助我解决此问题的建议,我将不胜感激。

【问题讨论】:

我看到您在 EndGetAccountInfo 方法中遇到了异常,但是您是否尝试按 F5 以保持代码运行并查看是否使用异常信息调用了 Proxy_GetAccountInfoCompleted?跨度> 我已更新问题以包括按 F5 后发生的情况。异常最终出现在应用程序的 Application_UnhandledException 处理程序中。 如果方法标记为[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)],请检查代理类 不,他们不是。我尝试将属性添加到相关方法中,但没有任何改变。 该属性在我很久以前为我的 WP7 应用程序生成的代理类中...属性(似乎与当前问题有关);我知道这实际上只是猜测,但是您是否尝试过重新生成/刷新代理或重新检查配置。你添加的时候设置的? 【参考方案1】:

我相信我遇到了同样的问题。我通过扩展代理类并在 Client 对象中调用私有 Begin.../End... 方法而不是在 Client 对象上使用公共自动生成的方法来解决它。

更多详情请见: http://cbailiss.wordpress.com/2014/02/09/wcf-on-windows-phone-unable-to-catch-faultexception/

【讨论】:

【参考方案2】:

框架似乎读取了您的 WsAccountInfo.Result 属性。 这会在客户端重新引发异常。 但是您应该是第一个阅读此属性的人。

我不知道您的 AuthenticationFault 类,它是否具有 DataContractAttribute 以及它是否像示例中的已知类型 http://msdn.microsoft.com/en-us/library/system.servicemodel.faultcontractattribute.aspx?

【讨论】:

以上是关于WP7:无法在对 WCF 服务的异步调用中捕获 FaultException的主要内容,如果未能解决你的问题,请参考以下文章

WCF服务需要调用异步

MonoTouch、Mono for Android 和 WP7 的认证 WCF 服务

调用 WCF 服务时如何在 WPF 中捕获异常

对 WCF 服务的异步调用不会保留 CurrentCulture

对 WCF 服务的异步调用不会保留 CurrentCulture

异步调用 WCF 服务并在新任务中等待它