WSDL 导出扩展中的定期异常

本文关键字:异常 扩展 WSDL | 更新日期: 2023-09-27 17:55:30

我有一个 SOAP 服务,现在已经运行了一个多月了。在过去的两周里,我们遇到了服务将随机开始生成异常的情况。每次,它们似乎都与导出扩展有关,并且错误始终遵循以下行:

在调用 WSDL 导出扩展时引发异常:System.ServiceModel.Description.DataContractSerializerOperationBehavior

"System.ArgumentException:命名节点来自不同的文档上下文"似乎是每次的根本原因。

困扰我的是这项服务在一个半月内没有改变,所以我很困惑我们突然会出现参数错误。这是否更能指示潜在问题(内存泄漏或类似问题)?

我对运行此计算机的访问权限非常有限,但可以根据需要尝试获取任何支持信息。以下是 wsdl 返回的完整异常:

    An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
    System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
     Endpoint: [endpoint name here... hidden for security] ----> System.ArgumentException: The named node is from a different document context.
       at System.Xml.XmlAttributeCollection.Append(XmlAttribute node)
       at System.ServiceModel.Description.SoapHelper.CreateSoapFaultBinding(String name, WsdlEndpointConversionContext endpointContext, FaultBinding wsdlFaultBinding, Boolean isEncoded)
       at System.ServiceModel.Description.MessageContractExporter.MessageBindingExporter.ExportMessageBinding(OperationDescription operation, Type messageContractExporterType)
       at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlEndpointConversionContext endpointContext, IWsdlExportExtension extension)
       --- End of inner ExceptionDetail stack trace ---
       at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
       at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
       at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
       at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
       at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleMetadataRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
       at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
       at SyncInvokeGet(Object , Object[] , Object[] )
       at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
       at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
       at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
       at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

编辑:我想澄清一下,该服务并不总是遇到此异常。有时 wsdl 返回正常,有时它会抛出此异常(我会说目前它是成功返回的 50/50 机会)。我无法弄清楚为什么。我最初的想法是环境问题,但如果是这种情况,我不知道该把托管团队指向哪里去看。

编辑2:自从询问最初的询问以来,我发现客户端已将服务放在多个服务器上,并且正在使用负载平衡器,我相信,这解释了我们得到的随机响应。我已经建议他们如何至少隔离问题,并将从那里开始。

WSDL 导出扩展中的定期异常

我有一个类似的错误。 在我的案例中,事实证明对WsdlExporter.GetGeneratedMetaData()的实例调用不是线程安全的,而是在Parallel.Foreach中调用的。 因此,添加简单的锁定解决了问题。

我们也受此影响,在我们的例子中,我们没有使用WsdlExporter或我们自己的任何东西:这只是发生在 WSDL URL 上,导致 HTTP 500 错误。 一旦问题发生,它就会对我们来说不断出错。 回收应用程序池时,问题消失了。

这似乎是Microsoft堆栈中某个错误;有关在 Microsoft Connect 上打开的错误报告,请参阅 https://connect.microsoft.com/VisualStudio/feedback/details/428531/wsdl-generation-error,该错误报告具有以下解决方法:

添加以下代码作为在每个应用程序域中执行的第一件事 托管 WCF 服务:

var soapHelperType = typeof(System.ServiceModel.Description.IContractBehavior).Assembly.GetType("System.ServiceModel.Description.SoapHelper");
var documentProperty = soapHelperType.GetProperty("Document",
BindingFlags.NonPublic | BindingFlags.Static);
documentProperty.GetValue(null, null);

(由于导致此问题的产品由单独的团队维护,因此我无法尝试验证此解决方法。

仅通过查看该错误很难判断。 它看起来不像通信错误,但以防万一,请确保您没有使用单例,因为您可能会造成瓶颈,Per Call 是默认方法,它适用于大多数情况,仅在您特别需要时才使用单例并包装逻辑以避免瓶颈。

似乎错误正在序列化数据,因此请确保数据协定和数据成员已明确定义,避免使用纯对象,使用类型化对象。将数据成员声明为属性

希望这有帮助,塞巴斯蒂安