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的主要内容,如果未能解决你的问题,请参考以下文章
MonoTouch、Mono for Android 和 WP7 的认证 WCF 服务
对 WCF 服务的异步调用不会保留 CurrentCulture