Периодическое исключение в расширении экспорта WSDL - PullRequest
10 голосов
/ 09 мая 2011

У меня есть сервис 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: С момента запроса первоначального запроса я обнаружилчто клиент разместил сервисы на нескольких серверах и использует балансировщик нагрузки, который, как мне кажется, учитывает случайные ответы, которые мы получаем.Я посоветовал им, как, по крайней мере, изолировать проблему и пойдем дальше.

Ответы [ 3 ]

5 голосов
/ 01 мая 2012

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

4 голосов
/ 26 июня 2013

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

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

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

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

2 голосов
/ 17 мая 2011

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

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

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

...