2009-02-06 2 views
4

У меня проблема, аналогичная этой question. У меня есть несколько веб-сервисов, которые я потребляю с WCF, которые все используют типы. Сами службы написаны на Java, и у меня нет доступа к ним. Общие типы имеют те же подписи, но svcutil.exe дает эту ошибку при запуске:Идентичные типы в отдельных веб-сервисах

Error: There was a validation error on a schema generated during export: 
    Source: 
    Line: 8 Column: 3 
    Validation Error: The complexType 'http://MyServer.MyService:CommonType' has already been declared. 

С CommonType с той же сигнатурой в обоих веб-сервисов потребляются. Вот как я звоню svcutil:

svcutil.exe /o:GeneratedServices.cs /n:*,MyNamespace.Generated http://MyServer.MyService1?WSDL http://MyServer.MyService2?WSDL 

Я знаю, что wsdl.exe имеет /mergeTypes флаг, который работает для этих услуг, но есть некоторые варианты на svcutil.exe, что я бы очень хотел использовать. У меня есть кто-то, кто показывает, что это возможно для меня, однако бэкэнд также использовал .NET и WCF, и я не увенчался успехом, с которым я пользуюсь.

ответ

5

Первый - это ровно то же самое? В частности, пространства имен SOAP должны совпадать (в дополнение ко всему остальному). Если они этого не делают, то они разные (несовместимые) типы; вам нужно будет использовать две разные ссылки (в разных пространствах имен C#, чтобы избежать конфликтов), и сдвинуть данные между двумя типами.

Если типы - это, то они все еще не работают, тогда вы можете использовать переключатель/r с svcutil для использования типов из существующей сборки. Попробуйте использовать его один раз, чтобы получить первые типы (только с одного из URL-адресов) - затем скомпилируйте этот код в сборку. Используйте svcutil против второй конечной точки с флагом/r, идентифицирующим сборку, которую вы создали несколько минут назад.

Примечание; связанная с этим тема состоит в том, чтобы написать partial class для одного или нескольких типов - например, чтобы предоставить методы преобразования/операторы для самих типов. Это может сделать вещи проще. Например, вы можете написать неявный (или явный) оператор статического преобразования между двумя подобными типами в разных пространствах имен.

0

ОТВЕТ, РАСШИРЕННЫЙ С ПЕЧАТИ (и контекст): И не забывайте, что svcutil.exe - это просто инструмент. Вы можете изменять или расширять сгенерированный код - запрет на него запрещен. Хотя, конечно, есть недостатки в настройке сгенерированного кода, и вы должны делать это только с широко открытыми глазами.

В ранние дни при установке гетерогенных клиентов и серверов вместе через веб-службы я регулярно прибегал к модификации созданного WSDL, изменяя код, сгенерированный из WSDL (я написал множество сценариев sed для обмена пространствами имен при подключении AXIS и. NET) и другие подгоняемые подходы. Некоторые из веб-сервисов, которые были вокруг самого длинного, все еще требуют этого. Одним из примеров является служба MS Office Research, которая вообще не отправляет WSDL ...

Другой подход, который может работать или не работать, заключается в расширении сгенерированного кода .NET через частичные классы. Это отличный способ настроить пространства имен XML, добавить дополнительные элементы (например, строку версии?) И сделать другие настройки. И когда вы повторно создаете код, ваши расширения не будут перезаписаны.

EDIT: Судя по нисходящему потоку, некоторые люди считают, что это слишком рискованно !!! Я полностью понимаю.

+0

Хотя это правда, это не всегда хорошая идея. Для * расширения * кода (методы добавления и т. Д.) Вы должны использовать неполный класс. Если вы измените код, у вас нет хорошего маршрута для обновления сервиса (если это требование), и вы рискуете его разбить (довольно легко сделать). –

+0

Да, конечно. Частичные классы делают это легко. – Cheeso

+0

Просто увидел этот прыжок (изменить) - я не думаю, что он заслуживает нисходящего; закрепится через несколько часов, когда я получу несколько голосов! (или когда я встаю ...) [исправлено] –

0

Поскольку он существует в обеих службах, тогда вы получаете два объявления после запуска svcutil для обеих служб. Я не думаю, что svcutil.exe достаточно умен, чтобы реанимировать тот же тип в обоих веб-сервисах.

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

+0

Это не сработает, потому что метод службы вызывает этот тип. Если MyServiceAlpha.DoSomething() принимает параметр MyServiceAlpha.Widget как параметр, он не будет принимать файл MyServiceBeta.Widget. – swilliams

+0

Это может быть так, но я уже создал службы, которые ранее использовали общие типы. Поэтому я не думаю, что только потому, что они используются двумя разными службами, это делает их разными. – AaronLS

Смежные вопросы