Периодическое исключение в расширении экспорта WSDL

#c# #web-services #exception #wsdl #invalidoperationexception

#c# #веб-сервисы #исключение #wsdl #исключение invalidoperationexception

Вопрос:

У меня есть служба SOAP, которая работает уже чуть больше месяца. За последние две недели у нас были ситуации, когда служба случайным образом начинала генерировать исключения. Каждый раз они, похоже, связаны с расширением экспорта, и ошибка всегда примерно в следующих строках:

Исключение было вызвано при вызове расширения экспорта WSDL: System.ServiceModel.Описание.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, Messageamp; 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[]amp; outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpcamp; rpc)
       at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpcamp; rpc)
       at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpcamp; rpc)
       at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
  

РЕДАКТИРОВАТЬ: я хотел уточнить, что служба не всегда попадает в это исключение. Иногда wsdl возвращается нормально, в других случаях он выдает это исключение (я бы сказал, что в настоящее время вероятность успешного возврата составляет 50/50). Я не могу понять, почему. Моя первоначальная мысль связана с проблемой среды, но если это так, я понятия не имею, куда направить команду хостинга для поиска.

РЕДАКТИРОВАТЬ 2: С момента запроса первоначального запроса я узнал, что клиент разместил службы на нескольких серверах и использует балансировщик нагрузки, который, я полагаю, учитывает случайные ответы, которые мы получаем. Я посоветовал им, как действовать, по крайней мере, изолируя проблему, и буду действовать дальше.

Ответ №1:

У меня была похожая ошибка на эту. В моем случае оказалось, что вызов экземпляра WsdlExporter.Функция GetGeneratedMetaData() не была потокобезопасной и вызывалась параллельно.Foreach. Таким образом, добавление простой блокировки решило проблему.

Ответ №2:

Мы также сталкиваемся с этим, и в нашем случае мы не используем WsdlExporter или что-то свое: это просто происходит при получении URL-адреса WSDL, вызывая ошибку HTTP 500. Как только проблема возникает, у нас все идет неправильно. Проблема устраняется при повторном использовании пула приложений.

Похоже, это ошибка где-то в стеке Microsoft; см. https://connect.microsoft.com/VisualStudio/feedback/details/428531/wsdl-generation-error для отчета об ошибке, открытого в Microsoft Connect, который имеет следующий обходной путь:

Добавьте следующий код в качестве первого, что нужно выполнить в каждом домене приложений, на котором размещены службы 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);
  

(Поскольку продукт, вызывающий это, поддерживается отдельной командой, я не смог попробовать и проверить это обходное решение.)

Ответ №3:

Сложно определить, просто взглянув на эту ошибку. это не похоже на ошибку связи, но на всякий случай убедитесь, что вы не используете singleton, поскольку вы можете создать узкое место, метод Per Call — это метод по умолчанию, и он работает в большинстве ситуаций, используйте singleton, только если вам это конкретно нужно, и оберните логику вокруг, чтобы избежать узких мест.

Похоже, ошибка заключается в сериализации данных, поэтому убедитесь, что ваши контракты данных и элементы данных четко определены, избегайте использования простых объектов, используйте типизированные объекты. Объявляйте элементы данных как свойства

Надеюсь, это поможет, Себастьян

Комментарии:

1. Спасибо за информацию, Себастьян. С момента запроса первоначального запроса я выяснил, что клиент разместил службы на нескольких серверах и использует балансировщик нагрузки, который, я полагаю, объясняет случайные ответы, которые мы получаем. Я посоветовал им, как действовать, по крайней мере, изолируя проблему, и буду действовать дальше. Еще раз спасибо!