Іноді додавання довідника служби WCF створює порожній reference.cs


159

Іноді додавання довідника служби WCF генерує порожній reference.cs, і я не можу посилатися на службу ніде в проекті.

Хтось із цим стикався?

Відповіді:


377

Як правило, я вважаю, що це проблема кодового роду, і більшість випадків це відбувається тому, що у мене конфлікт типу імен, який він не міг вирішити.

Якщо ви клацніть правою кнопкою миші на довідці служби та натисніть кнопку "Налаштувати" та зніміть прапорець "Типи повторного використання у збірних посиланнях", це, ймовірно, вирішить проблему.

Якщо ви використовували якийсь аспект цієї функції, можливо, вам потрібно буде переконатися, що ваші імена очищені.


5
Коли це сталося зі мною, я виявив, що мені також потрібно змінити Тип колекції з ObjectModel.ObservableCollection на Generic.List
Yossi Dahan

2
Сталося зі мною, тому що я додався до часткового класу.
Макотосан

2
Однак якщо ви хочете використовувати типи певної збірки, ви можете вибрати саме цю збірку, і вона працює так само добре (принаймні в моєму випадку), ta
Dead.Rabit

26
Мені здається, що я отримую в середньому 50 балів на тиждень від цього питання навіть через 6 років. Давай МС, виправте це. Принаймні, дайте розробникам деякі відгуки, коли це погано, замість того, щоб вони дивилися на порожній файл.
Андерсон Імес

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, то рекомендую напевно перевірити, що ваші спільні типи точно однакові на вашому клієнті та сервері. В іншому випадку ви, швидше за все, зіткнетеся з цим питанням.


У моєму випадку це сталося після того, як я посилався на збори, які також посилалися на мою службу 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.

Це мене зовсім спотикало. Незважаючи на важкий гуглінг та дійсно швидше перехрестя, і переглянувши кар’єру водія автобуса, я нарешті подумав, чому це справно працює на коробці розробки. Чи може це бути проблемою конфігурації IIS?

Я одночасно віддалявся як у вікна розробки, так і в прямому ефірі, і на кожному я запускав диспетчера IIS (запуск IIS 7.5). Далі я пройшов усі налаштування конфігурації у кожному вікні, порівнявши значення на кожному сервері.

І в цьому проблема: У розділі "Налаштування SSL" для сайту переконайтеся, що прапорець "Потрібно SSL", і перевірте перемикач Клієнтські сертифікати на "Прийняти". Проблема виправлена!


5

Я вважаю, що це трапляється часто, коли я додаю посилання, видаляю його, а потім повторно додаю службу з тим самим іменем. Здається, конфлікти типів викликані старими файлами, які залишаються десь, які Visual Studio все ще може бачити. Все, що мені потрібно зробити, щоб виправити це, - це очищення перед додаванням нової посилання.

  1. Видаліть посилання служби, що має проблеми.
  2. Клацніть на назві проекту в Провіднику рішень, щоб виділити проект.
  3. Клацніть правою кнопкою миші на посилання на проект.
  4. У верхній частині списку контекстів натисніть пункт « Очистити» .
  5. Додайте довідку про службу, як зазвичай.

Сподіваюся, це допомагає.


3

У мене була ця проблема із Silverlight 5, оновленим з попередньої версії.

Навіть повторне додавання посилання на службу все ж дало мені порожні Reference.cs

Мені в кінцевому підсумку довелося створити абсолютно новий проект і заново створити довідку про обслуговування. Це щось, що слід спробувати, якщо ви витратили на це більше півгодини. Навіть якщо ви вирішили виправити оригінальний проект, ви можете спробувати це, щоб побачити, що відбувається, а потім попрацюйте назад, щоб спробувати усунути проблему.

Я ніколи не з'ясовував, в чому саме полягає проблема - але, можливо, щось у файлі .csproj не було оновлено або деякі налаштування пішли не так.


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

Моя проблема полягала в тому, що я залишив " мекс " в кінці свого посилання на веб-службу.

Замість " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex "

Використовуйте " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc "


Це настільки очевидно, але так просто не помітити або відпустити як неважливе.
Карл Онагер

1

Метод, який працював для мене в моєму випадку, прочитавши ці відповіді безрезультатно, полягав у тому, щоб просто прокоментувати весь мій контракт і розрядити біти, поки він більше не працює, у бінарний спосіб пошуку. Це звужує кривдний біт коду.

Тоді ви просто повинні здогадатися, що з цим кодом не так.

Звичайно, допомогли б деякі відгуки про помилки в інструменті.

Я пишу договір на веб-сервіс. У мене був перелік заповнення заповнення без членів. Це добре. Але якщо я використовую його у властивості іншого класу та повторно використовую контрактний dll на клієнті, кодеген вибухає без повідомлення про помилку. Запуск svcutil.exe не допоміг, він просто не зміг вивести файл CS, не зазначивши, чому.


Коментуючи всі контракти на експлуатацію, працювали на мене. Я розглядав неправильних методів як винуватця. Дякуємо за підхід до вирішення неполадок.
фіз

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файл, який я включив у свій проект і мав намір скористатися послугою.


0

Як зазначає @dblood, головний біль полягає в DataContractSerializer, який типово повторно не використовує типи. Тут вже є кілька відповідей, так що я розпочну з додавання деяких плюсів і мінусів про це:

  • Прапор «IsReference» викликає багато клопоту, але його видалення не завжди є відповіддю (зокрема: в ситуаціях з рекурсією).
  • Основне питання полягає в тому, що договір даних якимось чином не відповідає іменам типів, хоча вони іноді є (так? Так, ви правильно це прочитали!). Мабуть, серіалізатор досить вибагливий, і справжню проблему знайти дуже важко.
  • Видалення "перевірки посилань" з "Налаштування довідки служби" працює, але залишає вас кілька реалізацій. Однак я часто використовую SOAP-інтерфейси через DLL. Крім того, у більшості зрілих SOA, які я знаю, кілька інтерфейсів служб реалізують та розширюють одні й ті ж класи інтерфейсів. Видалення перевірки "використання посилань на типи" призводить до ситуації, коли ви більше не можете просто передавати об'єкти.

На щастя, якщо ви контролюєте свою послугу, є просте рішення, яке вирішує всі ці проблеми. Це означає, що ви все ще можете повторно використовувати сервісні інтерфейси через DLL - що є IMO обов’язковим для правильного рішення. Ось як працює рішення:

  1. Створіть окремий інтерфейс DLL. У цю DLL включіть всі DataContract та ServiceContract; розмістіть 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 використовувати (правильні) типи послуг, минаючи генерацію проксі. Зрештою, у вас вже є ці заняття.

Професійні:

  1. Ви обминаєте процес svcutil.exe, що означає, що у вас немає проблем з IsReference
  2. Типи та назви DataContract є правильними за визначенням; зрештою, і сервер, і клієнт використовують саме те саме визначення.
  3. Якщо ви розширите API чи використовуєте типи з іншої DLL, (1) та (2) все ще утримуєтесь, тож у вас не виникне ніяких проблем.

Мінуси:

  1. Методи синхронізації - це біль, оскільки ви не генеруєте проксі-синхронізацію. Як результат, я б не рекомендував робити це в додатках Silverlight.

0

У мене також виникла помилка посилання на сервіс під час роботи з посиланнями на проекти з обох сторін (сервісний проект та проект, що мають посилання на послугу). Якщо, наприклад, .dll посилається на проект називається "Contoso.Development.Common", але назва проекту просто скорочується до "Загальне", також посилання на цей проект називаються просто "Загальні". Служба, однак, очікує посилання на "Contoso.Development.Common" для розв'язання класів (якщо ця опція активована в довідкових параметрах служби).

Тож з Explorer ми відкрили папку проекту, що посилається на службу та "спільний" -проект. Там я редагую файл проекту 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


0

Я зіткнувся з подібним питанням вчора під час розробки. Я дізнався, що використовую одне й те саме простір імен у двох різних версіях контрактів.

У нас є 2 версії контрактів, наприклад, версія4 та версія5. Я скопіював усі договори з версії4 та перейменував увесь простір імен з версії4 до версії5. Роблячи це, я забув перейменувати простір імен з v4 на v5 в одному з файлів. Через конфлікт у просторі імен файл Reference.cs був порожнім.

Цю проблему важко усунути, оскільки під час генерації посилання на сервіс ви не отримуєте жодного повідомлення про помилку. Щоб визначити цю проблему, я вручну підтвердив усі нові файли, які я створив. Є й інші шляхи вирішення цього питання. Це перший крок, який слід зробити перед тим, як перейти до інших варіантів.


0

Завдяки посаді Джона Сондерса вище, яка дала мені думку заглянути у вікно помилок. Я цілий день сипав головою, і я дивився у вихідне вікно на будь-яку помилку.

У моєму випадку винуватець був ІЗеріалізаційним. У мене є клас DataContract з властивістю DataMember типу Виняток. Ви не можете мати жодного типу DataMember, який має ключове слово ISerializable. У цьому Винятку є ISerializable, як тільки я видалив його, все працювало як шарм.


0

При спробі усунення цієї проблеми svcutil я отримав помилку, про яку йдеться у відповіді dblood ("тип посилання не можна використовувати, оскільки він не відповідає імпортованому DataContract").

У моєму випадку основна причина здавалася типом enum, який мав атрибут DataContract, але члени якого не були позначені атрибутом EnumMember. Клас проблемsvcutil вказували, мав властивість із цим типом enum.

Це краще підходить як коментар до відповіді dblood, але для цього недостатньо представників ...


0

У моєму випадку у мене було рішення з проектом VB Web Forms, який посилався на C # UserControl. І VB проект, і CS проект мали Посилання на одну службу. Посилання з'явилося в розділі Службові посилання в проекті VB та в групі Підключені послуги в проекті CS (Framework).

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


0

Виконайте такі дії:

  1. Видалити довідку служби
  2. Закрити Visual Studio
  3. Видалити / Bin та / Obj папки.
  4. Відкрити візуальну студію.
  5. Додайте довідку служби.
  6. Ласкаво просимо :)

Здається, що деякі посилання залишаються в цих папках під час додавання послуги, викликаючи помилки під час автоматичного генерування коду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.