【问题标题】:Two-way WCF service operation returns no reply instead of an exception双向 WCF 服务操作返回不回复而不是异常
【发布时间】:2010-10-15 20:06:04
【问题描述】:

我有两个不同的 WCF 服务主要执行基本的 CRUD 操作。对于这两种服务,无论客户端如何,如果服务抛出异常该异常将不会返回给客户端。事实上,我能看到实际异常的唯一方法是在服务中打开跟踪并查看跟踪文件。

无论是否抛出异常,这都是正确的。例如,如果我发送的字符串值的长度大于我的服务绑定配置所允许的长度,它将生成带有以下消息的 NetDispatcherFaultException 异常,如预期的那样:

格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数 http://tempuri.org/:newItem 时出错。 InnerException 消息是“反序列化 Organization.Division.Application.Service.AddNewItem 类型的对象时出错。 读取 XML 数据时已超出最大字符串内容长度配额 (8192)。可以通过更改创建 XML 阅读器时使用的 XmlDictionaryReaderQuotas 对象的 MaxStringContentLength 属性来增加此配额。第 1 行,位置 20157.'。

问题是服务没有返回这个异常,而是服务抛出一个带有异常消息的ArgumentNullException:

值不能为空。
参数名称:消息

...我的客户端只是给了我这个错误(无论我的客户端是 ASP.NET 网页、WCF 测试客户端还是其他客户端都是如此):

调用服务失败。可能原因:服务离线或无法访问;客户端配置与代理不匹配;现有代理无效。有关更多详细信息,请参阅堆栈跟踪。您可以尝试通过启动新代理、恢复到默认配置或刷新服务来进行恢复。
错误详情:
接收到http://localhost/Services/MyAwesomeS3rv1c3/DoSomethingGrrreat.svc 的 HTTP 响应时出错。这可能是由于服务端点绑定未使用 HTTP 协议。这也可能是由于服务器中止了 HTTP 请求上下文(可能是由于服务关闭)。有关详细信息,请参阅服务器日志。

当我查看服务跟踪时,我还看到了这个警告:请求/回复操作 AddNewItem 没有回复消息。

我假设我在做系统性错误,因为无论在多个服务和每个服务的多个方法中引发的底层异常如何,都会发生这种情况。我只是无法辨别问题所在。我只想把错误返回给客户端。

有关其他背景信息,我确实在服务的 web.config 中的 <serviceBehavior><behavior>... 下设置了以下设置:

<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>

...我正在使用 wsHttpBinding 和 mex 绑定。

最后,这似乎是最近才发生的行为变化(即,客户端过去常常看到服务抛出的实际异常)。我只是无法弄清楚可能发生了什么变化。

【问题讨论】:

  • FWIW,我最近遇到了完全相同的问题:找到它的唯一方法显然是使用 WCF 跟踪。幸运的是,就我而言,它发生在开发过程中。
  • 感谢您的评论。如果没有 WCF 跟踪,我会完全迷路!对于其他任何人,msdn.microsoft.com/en-us/library/ms732023.aspx 提供了有关如何设置跟踪的详细信息。现在我只需要弄清楚如何将这些异常详细信息传递回客户端 :-)

标签: wcf


【解决方案1】:

就我而言,我使用的是企业库来记录异常。日志记录的配置显然不正确。但是,WCF 服务跟踪并未显示这一点。

跟踪确实显示了正确处理/捕获的底层异常(无论是 sql 错误还是其他)。之后,ServiceChannel 莫名其妙地被关闭了。由于没有要返回的回复消息,因此生成了 ArgumentNullException。

所有这一切都是因为底层异常的错误处理中的异常,该异常从未在跟踪中显示。调试服务显示 Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write 实际上是在抛出自己的异常,该异常未处理并隐藏在视图之外。修复该异常(或者只是暂时关闭日志记录 - 当然)解决了问题。

只是表明有时跟踪不够好,您仍然必须能够调试。

【讨论】:

    【解决方案2】:

    如果我没记错的话,我认为这取决于异常发生的时间:即在您的情况下,配额异常在管道中发生得太早,而来自客户端的传入消息仍在反序列化 - 因此服务器只是中止连接,因为它根本不认为传入消息是有效请求(因为它不能被反序列化),所以从它的角度来看,没有什么可回复的。

    【讨论】:

    • 好主意。不过,我确实有同样的问题,但我不会认为会在管道早期发生的潜在异常。例如,我的服务执行基本的创建操作,向数据库中插入一行,使用一对列作为具有唯一约束的唯一键。如果违反了该约束(即,如果服务尝试插入重复项),则会按预期抛出异常。但是,WCF 服务不会将异常返回给客户端。
    • 您能否打开 WCF 跟踪,捕获您描述的情况的跟踪,然后查看确切的异常(及其完整的堆栈跟踪)是什么? (使用 WCF 跟踪查看器工具)
    • 1 个示例异常是 SqlTypeException:SqlDateTime 溢出。堆栈跟踪: SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan 值) SqlTypes.SqlDateTime.FromDateTime(DateTime 值) SqlClient.MetaType.FromDateTime SqlClient.TdsParser.WriteValue SqlClient.TdsParser.TdsExecuteRPC SqlClient.SqlCommand.RunExecuteReaderTds SqlClient.SqlCommand.RunExecuteReader SqlClient.SqlCommand。 RunExecuteReader SqlClient.SqlCommand.ExecuteReader SqlClient.SqlCommand.ExecuteDbDataReader Common.DbCommand.ExecuteReader Mapping.Update.Internal.DynamicUpdateCommand.Execute Mapping.Update.Internal.UpdateTranslator.Update
    • 很抱歉将堆栈跟踪聚集到评论中!该异常不会返回给用户。相反,它后面是“请求/回复操作 AddItem 没有回复消息”的警告,然后是“值不能为空。参数名称:消息”的 ArgumentNullException。
    猜你喜欢
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多