it-swarm.com.ru

Иногда при добавлении ссылки на службу WCF создается пустой файл reference.cs

Иногда при добавлении ссылки на службу WCF создается пустой файл reference.cs, и я не могу ссылаться на службу где-либо в проекте.

Кто-нибудь сталкивался с этим?

151
Matt

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

Если вы щелкнете правой кнопкой мыши по ссылке на свою службу и нажмете «Настройка» и снимите флажок «Повторное использование типов в ссылочных сборках» это, вероятно, решит проблему.

Если вы использовали какой-либо аспект этой функции, вам может потребоваться очистить ваши имена.

367
Anderson Imes

Как указано в принятом ответе, проблема со ссылками на типы при повторном использовании типов, вероятно, является причиной. Я обнаружил, что если вы не можете легко определить проблему, то использование командной строки svcutil.exe поможет вам выявить основную проблему (как отмечает Джон Сондерс).

В качестве улучшения здесь приведен быстрый пример использования svcutil.

svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:\MyCode\MyAssembly\bin\debug\MyAssembly.dll"

Куда:

  • / t: код генерирует код по заданному URL
  • / d: указать каталог для вывода
  • / r: указать ссылочную сборку

Полная ссылка на командную строку svcutil здесь: http://msdn.Microsoft.com/en-us/library/aa347733.aspx

Как только вы запустите svcutil, вы увидите, что исключение выдается при импорте. Вы можете получить сообщение такого типа об одном из ваших типов: «ссылочный тип не может быть использован, поскольку он не соответствует импортированному DataContract».

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

Существуют и другие, более сложные сценарии, которые могут вызывать исключения такого типа и приводить к пустым файлам reference.cs. Вот один пример .

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

36
dblood

Я целый день ломал голову над этой проблемой. Я только что исправил это. Вот как...

Служба имела для работы через SSL (т.е. она находится в https://mydomain.com/MyService.svc )

Добавление ссылки на службу в службу WCF на сервере разработки работало просто отлично.

Развертывание точной той же сборки службы WCF на работающем производственном сервере, затем переключение на клиентское приложение и настройка ссылки на службу для указания на действующую службу не показывали ошибок, но приложение не собиралось: Оказывается, что файл Reference.cs справочной службы был полностью пустым! Обновление сервисной ссылки не имело никакого значения. Очистка раствора не помогла. Перезапуск VS2010 не имел значения. Создание нового пустого решения, запуск консольного проекта и добавление ссылки на службу в действующую службу показало точно такую ​​же проблему.

Я не думал, что это из-за конфликтующих типов или чего-то еще, но какого черта - я перенастроил ссылку на службу WCF, сняв флажок «Повторное использование типов во всех ссылочных сборках». Нет радости; Я поставил галочку обратно.

Следующим шагом было попробовать svcutil на ссылочном URL, чтобы увидеть, поможет ли это выявить проблему. Вот команда: 

svcutil /t:code https://mydomain.com/MyService.svc /d:D:\test

Это произвело следующее:

Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 4.0.30319.1]
Copyright (c) Microsoft Corporation.  All rights reserved.

Attempting to download metadata from 'https://mydomain.com/MyService.svc' using WS-Metadata Exchange or DISCO.
Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Schema with target namespace 'http://mynamespace.com//' could not be found.
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://mynamespace.com//']/wsdl:portType[@name='IMyService']


Error: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://mynamespace.com//']/wsdl:portType[@name='IMyService']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='WSHttpBinding_IMyService']


Error: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='WSHttpBinding_IMyService']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:service[@name='MyService']/wsdl:port[@name='WSHttpBinding_IMyService']


Generating files...
Warning: No code was generated.
If you were trying to generate a client, this could be because the metadata documents did not contain any valid contracts or services
or because all contracts/services were discovered to exist in /reference assemblies. Verify that you passed all the metadata documents to the tool.

Warning: If you would like to generate data contracts from schemas make sure to use the /dataContractOnly option.

Это меня полностью озадачило. Несмотря на интенсивный поиск в Google, а также на то, чтобы по-настоящему скучать и пересмотреть свою карьеру в качестве водителя автобуса, я наконец-то подумал, почему это хорошо работает на коробке разработки. Может ли это быть проблема конфигурации IIS?

Я удаленно работал одновременно как с разработчиками, так и с живыми блоками, и на каждом из них запускал IIS Manager (работает IIS 7.5). Затем я просмотрел каждый параметр конфигурации в каждом окне, сравнивая значения на каждом сервере.

И есть проблема: в разделе «Настройки SSL» для сайта убедитесь, что установлен флажок «Требовать SSL», и установите переключатель «Сертификаты клиента» на «Принять». Проблема исправлена!

11
Matt Kane

Когда это происходит, посмотрите в окне «Ошибки» и окне «Вывод», чтобы увидеть, есть ли какие-либо сообщения об ошибках. Если это не помогает, попробуйте запустить svcutil.exe вручную и посмотрите, есть ли какие-либо сообщения об ошибках.

9
John Saunders

Я обнаружил, что это часто происходит всякий раз, когда я добавляю ссылку, удаляю ее, а затем повторно добавляю службу с тем же именем. По-видимому, конфликты типов вызваны тем, что старые файлы остаются где-то, что Visual Studio все еще может видеть. Все, что мне нужно сделать, чтобы это исправить, это очистить перед добавлением новой ссылки.

  1. Удалите сервисную ссылку, имеющую проблемы.
  2. Нажмите на название проекта в Solution Explorer , чтобы выделить проект.
  3. Щелкните правой кнопкой мыши ссылку на проект.
  4. В верхней части контекстного списка щелкните элемент Очистить .
  5. Добавьте ссылку на сервис, как обычно.

Надеюсь это поможет.

4
user1353936

У меня была эта проблема с Silverlight 5, обновленной с предыдущей версии.

Даже повторное добавление ссылки на сервис все равно дало мне пустой Reference.cs

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

Я так и не выяснил, в чем именно проблема - но, возможно, что-то в файле .csproj не было обновлено или некоторые настройки пошли не так.

3
Simon_Weaver

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

[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }

[CollectionDataContract(Name="AItems", ItemName="A")]  // Wrong
public class CollectionB : List<B> { }

Я исправил ошибку, пройдя через мой проект и убедившись, что каждый атрибут Name и ItemName уникален:

[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }

[CollectionDataContract(Name="BItems", ItemName="B")]  // Corrected
public class CollectionB : List<B> { }

Затем я обновил ссылку на сервис, и все снова заработало. 

1
Jon Person

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

Тогда вам просто нужно угадать, что не так с этим кодом.

Конечно, некоторые отзывы об ошибках в инструменте помогли бы.

Я пишу контракт веб-службы. У меня был список-заполнитель без членов. Это нормально. Но если я использую его в свойстве другого класса и повторно использую контрактную DLL на клиенте, кодовый код взрывается без сообщения об ошибке. Запуск svcutil.exe не помог, просто не удалось вывести файл cs без указания причины.

1
JoshuaLawrence

Следующее не перечислено здесь, и это было решение, которое я принял (SvcUtils был полезен при просмотре сообщения об ошибке. Однако ошибка, которую я получил, была wrapper type message cannot be projected as a data contract type since it has multiple namespaces. То есть я следовал этому примеру и узнал о wsdl.exe через this сообщение).

В моем случае простое выполнение wsdl [my-asmx-service-address] сгенерировало беспроблемный файл .cs, который я включил в свой проект и создал для использования службы.

1
Veverke

Моя проблема заключалась в том, что я оставил «mex» в конце своей ссылки на веб-сервис.

Вместо " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex "

Используйте " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc "

1
sagesky36

В моем случае у меня было решение с проектом VB Web Forms, который ссылался на C # UserControl. И проект VB, и проект CS имели ссылку на службу для одной и той же службы. Ссылка появилась в разделе «Ссылки на услуги» в проекте VB и ​​в группе «Подключенные службы» в проекте CS (framework).

Чтобы обновить ссылку на службу (т. Е. Чтобы файл Reference.vb не был пустым) в проекте веб-форм VB, мне нужно было удалить проект CS, а затем обновить VB Service Reference, затем добавьте проект CS обратно в решение.

0
INFOequipt

При попытке решить эту проблему с помощью svcutil я получил ошибку, указанную в ответе dblood («ссылочный тип не может быть использован, поскольку он не соответствует импортированному DataContract»).

В моем случае основной причиной, по-видимому, был тип enum с атрибутом DataContract, но члены которого не были отмечены атрибутом EnumMember. Класс проблемы, на который указывался svcutil, имел свойство с этим типом перечисления.

Это было бы лучше в качестве комментария к ответу dblood, но недостаточно репов для этого ...

0
Platedslicer

У меня также была проблема неработающих ссылок на сервисы при работе с ссылками на проект с обеих сторон (проект сервиса и проект, имеющий ссылку на сервис). Если .dll ссылочного проекта, например, называется «Contoso.Development.Common», но имя проекта просто сокращается до «Common», ссылки на этот проект также называются просто «Common». Служба, однако, ожидает ссылку на «Contoso.Development.Common» для разрешения классов (если эта опция активирована в опциях службы ссылки).

Итак, с помощью Explorer я открыл папку проекта, которая ссылается на сервис и «Common» -проект. Там я редактирую файл проекта VS (.csproj) с помощью блокнота. Найдите имя ссылочного проекта (в данном примере «Common.csproj»), и вы быстро найдете запись конфигурации, представляющую ссылку на проект.

Я изменился 

<ProjectReference Include="..\Common\Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Common</Name> </ProjectReference>

в

<ProjectReference Include="..\Common\Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Contoso.Development.Common</Name> </ProjectReference>

Важно поменять имя ссылки на имя dll, на который ссылается проект в качестве вывода.

Затем переключитесь обратно на VS. Там вам будет предложено перезагрузить проект, так как он был изменен за пределами VS. Нажмите кнопку перезагрузки.

После этого добавление и обновление ссылки на службу работали так, как ожидалось.

Надеюсь, что это также помогает кому-то еще.

RegardsMH

0
Martin Jesch

Спасибо Джону Сондерсу, опубликовавшему выше пост, который дал мне идею заглянуть в окно ошибок. Я весь день мешал в голове и смотрел в окно вывода на наличие ошибок. 

В моем случае виновник был ISerializable. У меня есть класс DataContract со свойством DataMember типа Exception. Вы не можете иметь DataMember типа, который имеет ключевое слово ISerializable. В этом исключении есть ISerializable, как только я убрал его, все заработало как шарм. 

0
Ziggler

Как указывает @dblood, основная проблема заключается в DataContractSerializer, который неправильно использует типы. Здесь уже есть несколько ответов, поэтому я начну с добавления плюсов и минусов по этому поводу:

  • Флаг IsReference вызывает много проблем, но его удаление не всегда является ответом (особенно: в ситуациях с рекурсией). 
  • Основная проблема заключается в том, что контракт данных как-то не совпадает с именами типов, даже если они иногда (да? Да, вы правильно прочитали!). Очевидно, что сериализатор довольно придирчив, и очень трудно найти реальную проблему.
  • Удаление «проверок ссылок» из «Настроить ссылку на службу» работает, но оставляет вам несколько реализаций. Однако я часто использую интерфейсы SOAP в библиотеках DLL. Кроме того, в большинстве известных мне SOA интерфейсы нескольких сервисов реализуют и расширяют одни и те же классы интерфейса. Удаление проверок «использование ссылочных типов» приводит к ситуации, когда вы просто не можете больше передавать объекты.

К счастью, если вы контролируете свои услуги, существует простое решение, которое решает все эти проблемы. Это означает, что вы все равно можете повторно использовать сервисные интерфейсы в библиотеках DLL, что является IMO, которое необходимо иметь для правильного решения. Вот как работает решение:

  1. Создайте отдельный интерфейс DLL. В эту DLL включите все DataContract и ServiceContract's; поместите ServiceContract на ваши интерфейсы.
  2. Вывести реализацию сервера из интерфейса.
  3. Используйте тот же DLL, чтобы создать клиент, используя ваш любимый метод. Например (IMyInterface является интерфейсом контракта на обслуживание):

    var httpBinding = new BasicHttpBinding();
    var identity = new DnsEndpointIdentity("");
    var address = new EndpointAddress(url, identity, new AddressHeaderCollection());
    var channel = new ChannelFactory<IMyInterface>(httpBinding, address);
    return channel.CreateChannel();
    

Другими словами: Не используйте функциональность «добавить ссылку на сервис» , но заставляйте WCF использовать (правильные) типы сервисов, минуя генерацию прокси. В конце концов, у вас уже есть эти классы.

Pro-х:

  1. Вы обходите процесс svcutil.exe, а это значит, что у вас нет проблем с IsReference
  2. Типы и имена DataContract являются правильными по определению; в конце концов, и сервер, и клиент используют одно и то же определение.
  3. Если вы расширяете API или используете типы из другой DLL, (1) и (2) по-прежнему остаются в силе, поэтому у вас не возникнет никаких проблем.

Минусы: 

  1. Методы A-Sync - это боль, так как вы не генерируете прокси A-Sync. В результате я бы не рекомендовал делать это в приложениях Silverlight.
0
atlaste

Я столкнулся с подобной проблемой вчера во время разработки. Я узнал, что использую одно и то же пространство имен в 2 разных версиях контрактов. 

У нас есть 2 варианта контрактов, например, версия 4 и версия 5. Я скопировал все контракты из версии 4 и переименовал все пространство имен из версии 4 в версию 5. При этом я забыл переименовать пространство имен с v4 на v5 в одном из файлов. Из-за конфликта пространства имен файл Reference.cs был пуст.

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

0
arif.khan.b