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

159

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

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

Matt
источник

Ответы:

377

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

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

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

Андерсон Имес
источник
5
Когда это случилось со мной, я обнаружил, что мне также нужно изменить тип коллекции с ObjectModel.ObservableCollection на Generic.List
Йосси Даан,
2
Произошло со мной, потому что я добавил к частичному классу.
Макотосан
2
Однако, если вы хотите использовать типы из конкретной сборки, вы можете выбрать именно эту сборку, и она будет работать так же хорошо (по крайней мере, в моем случае),
т.е
26
Меня поражает, что я получаю в среднем 50 баллов в неделю от этого вопроса даже через 6 лет. Давай MS, исправить это. По крайней мере, дайте разработчикам обратную связь, когда все пойдет не так, вместо того, чтобы смотреть на пустой файл.
Андерсон Имес
1
9 лет спустя, и вы все еще помогаете. Спасибо!
параметр
38

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

dblood
источник
В моем случае это произошло после того, как я ссылался на сборку, которая также ссылалась на мой сервис WCF. Удаление этой сборки из списка сборок для обмена типами с исправленными.
xr280xr
Я получал бессмысленное сообщение об ошибке (просто пространство имен) при добавлении ссылки на сервис, и это указывало на проблему.
bcampolo
12

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

Джон Сондерс
источник
@ Как запустить svcutil.exe? Вы можете помочь мне ?
Арул Сирджан
@Arul: используйте Google, чтобы найти информацию о svcutil.exe.
Джон Сондерс
2
Не уверен, что Microsoft прочитала этот пост, но даже просто показывала окно сообщения с сообщениями об ошибках и предупреждениях вместо того, чтобы просто молча помещать их в (минимизированное, в моем случае) окно Список ошибок, сделало бы это, так что мне не нужно было Google этот. В качестве альтернативы, я думаю, было бы полезно, чтобы вкладка отображалась красным или желтым цветом при появлении новых предупреждений / ошибок?
JRH
12

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

Служба должна была работать через 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», и установите переключатель «Сертификаты клиента» на «Принять». Проблема исправлена!

Мэтт Кейн
источник
5

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

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

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

user1353936
источник
3

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

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

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

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

Simon_Weaver
источник
1
Хорошо, оказалось, что я ссылаюсь на старую версию System.Xml.Linq- так что проверьте версии всех ваших DLL, если вы переключили версии
Simon_Weaver
1

Если вы недавно добавили коллекцию в свой проект, когда это начало происходить, проблема может быть вызвана двумя коллекциями, которые имеют один и тот же атрибут 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

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

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

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

sagesky36
источник
Это так очевидно, но так легко пропустить или отклонить как неважное.
Карл Онагер
1

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

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

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

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

JoshuaLawrence
источник
Комментирование всех контрактов работало на меня. Я смотрел на неправильные методы в качестве виновника. Спасибо за возвращение к основному подходу к устранению неполадок.
fizch
1

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

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

Veverke
источник
0

Как указывает @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.
atlaste
источник
0

У меня также была проблема неработающих ссылок на сервисы при работе с ссылками на проект с обеих сторон (проект сервиса и проект, имеющий ссылку на сервис). Если, например, .dll указанного проекта называется «Contoso.Development.Common», но имя проекта просто сокращается до «Common», ссылки на этот проект также называются просто «Common». Однако служба ожидает ссылку на «Contoso.Development.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. Нажмите кнопку перезагрузки.

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

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

С уважением MH

Martype
источник
0

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

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

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

arif.khan.b
источник
0

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

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

Ziggler
источник
0

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

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

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

Platedslicer
источник
0

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

Чтобы обновить ссылку на службу (т. Е. Чтобы файл Reference.vb не был пустым) в проекте веб-форм VB, мне нужно УДАЛИТЬ ПРОЕКТ CS, затем обновить ссылку на службу VB, а затем добавить проект CS обратно в решение.

INFOequipt
источник
0

Следуй этим шагам:

  1. Удалить ссылку на сервис
  2. Закрыть Visual Studio
  3. Удалить папки / Bin и / Obj.
  4. Откройте Visual Studio.
  5. Добавьте сервисную ссылку.
  6. Пожалуйста :)

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

Exel Gamboa
источник