Клиент WCF, вызывающий веб-службу Java: XmlSerializer не может найти производные типы - PullRequest
0 голосов
/ 15 июля 2011

Это похоже на фундаментальную проблему веб-сервисов. Однако элегантное решение неуловимо, основываясь на некоторых исследованиях, которые я смог сделать. Я думаю, что-то здесь не хватает

Я использую клиент WCF для подключения к внешней веб-службе, которую я не могу контролировать. Внешний WS основан на Java. Существует множество сборок, которые предоставляются для вызова методов в веб-сервисе. Эти сборки имеют базовые классы и производные классы. Методы веб-службы могут принимать базовый класс в качестве параметра, тогда как из клиента WCF я создаю экземпляр класса Derived и передаю его методу.

Чтобы смоделировать этот сценарий, я создал небольшой проект с одним ClassLibrary, который имеет BaseClass и DerivedClass с одним методом.

Затем я создаю веб-сервис asmx и добавляю в него метод HelloWorld. Я добавляю ссылку на ClassLibrary. Этот метод принимает параметр типа BaseClass.

Затем я создаю ссылку на службу для веб-службы ASMX. В прокси-классе я добавляю XmlSerializerFormatAttribute к методу, если его там уже нет.

Из клиента WCF я вызываю веб-метод ASMX

BaseClass bc = new Derived ();

ServiceReference1.TestService ts = new WCFTest.ServiceReference1.TestService ();

lbl1.Text = (c1.HelloWorld (bc));

Вызов не удался с ошибкой Тип ClassLib.Derived не ожидался. Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, которые статически не известны.

Единственный способ вызвать этот метод веб-службы - добавить атрибут XmlInclude в BaseClass в ClassLibrary. В моем сценарии эта библиотека является dll, предоставленным внешним поставщиком. Я не могу добавить атрибуты к его классам. Я посмотрел DataContractSerializer и KnownTypes и XmlSerializer ctor. Однако эти решения, по-видимому, не применимы в моем сценарии.

Как я могу заставить XMLSerializer видеть производные классы в сборках, на которые я ссылаюсь в клиенте WCF? Есть ли элегантное решение?

Спасибо, Hem

1 Ответ

0 голосов
/ 15 июля 2011

Включение вашего собственного сопоставления типов для XmlSerializerOperationBehavior может просто работать, но я не пробовал этого (см. GetXmlMappings).

http://msdn.microsoft.com/en-us/library/system.servicemodel.description.xmlserializeroperationbehavior.aspx

В качестве альтернативы, принудительное использование DataContractSerializer черезDataContractSerializerOperationBehavior (в отличие от XmlSerializerOperationBehavior, который он использует сейчас) также может работать, если вы укажите свои собственные известные типы

http://msdn.microsoft.com/en-us/library/ms576751%28v=vs.85%29.aspx

Наконец, в качестве последнего средства вы можете принудительно использоватьDataContractSerializer, используя DataContractSerializerOperationBehavior, затем укажите свой собственный DataContractSurrogate, чтобы принудительно использовать XmlSerializer, где вы можете передавать пользовательские типы в его конструктор (что обходит требование для атрибута XmlInclude).

http://msdn.microsoft.com/en-us/library/ms751540.aspx

Надеюсь, что помогает.

...