有时添加WCF服务参考会生成一个空的参考。


159

有时添加WCF服务引用会生成一个空的reference.cs,而我无法在项目中的任何地方引用该服务。

有人遇到过这个吗?

Answers:


377

通常,我发现这是一个代码生成问题,大多数情况下是因为我遇到无法解决的类型名称冲突。

如果右键单击服务引用,然后单击“配置,然后取消选中 “在引用的程序集中重新使用类型”,则可能会解决该问题。

如果您正在使用此功能的某些方面,则可能需要确保清除了您的姓名。


5
当我遇到这种情况时,我发现我还需要将Collection Type从ObjectModel.ObservableCollection更改为Generic.List
Yossi Dahan 2010年

2
发生在我身上的原因是我加入了部分课程。
Makotosan 2012年

2
但是,如果您想使用特定程序集中的类型,则可以只选择该程序集,它也可以正常工作(至少在我的情况下),ta
Dead.Rabit 2013年

26
令我震惊的是,即使是6年之后,我平均每周从这个问题中获得50分。快来MS,解决这个问题。至少在效果不佳时,至少要给开发人员一些反馈,而不是让他们盯着空白文件。
安德森·埃姆斯

1
9年后,您仍在提供帮助。谢谢!
参数

38

正如公认的答案所指出的,重用类型时的类型引用问题可能是罪魁祸首。我发现当您无法轻松确定问题时,然后使用svcutil.exe命令行将帮助您揭示潜在的问题(正如John Saunders指出的那样)。

作为增强功能,这里是使用svcutil的快速示例。

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

哪里:

  • / t:code从给定的URL生成代码
  • / d:指定输出目录
  • / r:指定参考程序集

完整的svcutil命令行参考在这里:http : //msdn.microsoft.com/zh-cn/library/aa347733.aspx

一旦运行svcutil,您应该看到导入引发的异常。您可能会收到有关您的一种类型的消息:“无法使用引用的类型,因为它与导入的DataContract不匹配”。

可以简单地指定这一点,因为所引用程序集中的一种类型与在DataContract中为该服务生成的类型有所不同。就我而言,我要导入的服务具有比共享程序集中的服务更新的类型。这不是很明显,因为例外中提到的类型似乎是相同的。不同的是该类型使用的嵌套复杂类型之一。

还有其他更复杂的情况,可能会触发这种类型的异常并导致空白的reference.cs。这是一个例子

如果遇到此问题,并且没有在数据协定中使用通用类型,也没有使用IsReference = true,那么建议您确定在客户端和服务器上共享类型是否完全相同。否则,您可能会遇到此问题。


就我而言,这是在我引用了一个程序集之后又引用了我的WCF服务之后发生的。从程序集列表中删除该程序集以共享固定类型。
xr280xr 2013年

添加服务引用时,我收到了毫无意义的错误消息(只是一个名称空间),这指出了问题所在。
bcampolo 2016年

12

发生这种情况时,请在“错误”窗口和“输出”窗口中查看是否有任何错误消息。如果那没有帮助,请尝试svcutil.exe手动运行,然后查看是否有任何错误消息。


@如何运行svcutil.exe?你能帮助我吗 ?
Arul Sidthan

@Arul:使用Google查找svcutil.exe上的信息。
约翰·桑德斯

2
不知道Microsoft是否阅读了这篇文章,甚至只是显示一个消息框来说明错误和警告,而不是仅将它们静默地放在(在我的情况下为最小)“错误列表”窗口中,所以我不需要Google这个。另外,我想当有新的警告/错误出现时,将选项卡显示为红色或黄色会很有用?
jrh

12

这个问题困扰我整整一整天。我已经解决了。这是如何做...

该服务必须在SSL上运行(即,它位于https://mydomain.com/MyService.svc

在开发服务器上向WCF服务添加服务引用就可以了。

在实时生产服务器上部署完全相同的WCF服务构建,然后切换到客户端应用程序,并将服务引用配置为指向实时服务,但没有显示错误,但该应用程序无法构建:事实证明,服务引用的Reference.cs文件完全为空!更新服务参考没有区别。清洁溶液无济于事。重新启动VS2010没什么区别。创建一个新的空白解决方案,启动一个控制台项目并将服务引用添加到实时服务中时,出现了完全相同的问题。

我不认为这是由于类型冲突或其他原因造成的,但是到底是什么-我通过取消选中“在所有引用的程序集中重用类型”来重新配置WCF服务引用。不高兴 我把复选标记放回去。

下一步是尝试在参考URL上使用svcutil,以查看这是否有助于发现问题。这是命令:

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> { }

我通过遍历项目并确保每个NameItemName属性都是唯一的来解决该错误:

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

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

然后,我刷新了服务参考,然后一切又恢复了。



1

在阅读了这些答案无济于事后,对我而言有效的技术只是以二进制搜索方式注释掉我的所有合同,并取消注释位,直到不再起作用。这样可以缩小令人讨厌的代码范围。

然后,您只需要猜测该代码出了什么问题。

当然,该工具中的一些错误反馈也会有所帮助。

我正在写一个Web服务合同。我有一个没有成员的占位符枚举。没关系。但是,如果我在另一个类的属性中使用它,然后在客户端上重新使用合同dll,则代码生成将爆炸而没有错误消息。运行svcutil.exe并没有帮助,只是输出了一个CS文件而未提及原因。


注释掉所有的运营合同都对我有用。我将错误的方法视为罪魁祸首。感谢您使用基本知识进行故障排除。
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文件,该文件包含在我的项目中并实例化为可以使用该服务。


0

正如@dblood指出的那样,主要的麻烦在于DataContractSerializer,它不能正确地重用这些类型。这里已经有一些答案,因此我将在此基础上添加一些优点和缺点:

  • “ IsReference”标志会带来很多麻烦,但是删除它并不总是答案(特别是:在具有递归的情况下)。
  • 潜在的问题是,即使某些时候数据协定有时也与类型名称不同(呵呵,是的,您没看错!)。显然,序列化器非常挑剔,很难找到真正的问题。
  • 从“配置服务参考”中删除“参考检查”是可行的,但是会给您带来多种实现。但是,我经常跨DLL重用SOAP接口。另外,在我所知道的大多数成熟的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”,但是项目名称被简称为“ Common”,则对该项目的项目引用也被命名为“ Common”。但是,该服务需要用于解析类的“ Contoso.Development.Common”引用(如果在服务引用选项中激活了该选项)。

因此,使用资源管理器,我打开了引用服务和“ 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


0

我昨天在开发过程中遇到了类似的问题。我发现我在2个不同版本的合同中使用相同的名称空间。

我们有2个版本的合同,例如版本4和版本5。我已经复制了版本4中的所有协定,并将所有名称空间从版本4重命名为版本5。在执行此操作时,我忘记在其中一个文件中将名称空间从v4重命名为v5。由于名称空间冲突,Reference.cs文件为空。

生成服务参考时没有收到任何错误消息,因此很难解决此问题。为了确定此问题,我将手动验证所有创建的新文件。还有其他方法可以解决此问题。这是您执行其他选择之前应该执行的第一步。


0

感谢上面的John Saunders帖子,它使我有了一个进入“错误”窗口的想法。我整天都在装袋,并且正在查看“输出”窗口中是否有任何错误。

就我而言,罪魁祸首是可序列化的。我有一个DataContract类,其DataMember属性的类型为Exception。您不能使用具有ISerializable关键字的任何类型的DataMember。在我移除此Exception之后,它就可以进行ISerializable了,一切都像一个符咒一样起作用。


0

尝试使用解决此问题时svcutil,我收到了dblood的答案中提到的错误(“无法使用引用类型,因为它与导入的DataContract不匹配”)。

在我的情况下,根本原因似乎是具有DataContract属性的枚举类型,但其成员未使用EnumMember属性标记。svcutil指向的问题类具有该枚举类型的属性。

作为对dblood的答案的评论,这会更合适,但对于此而言,代表不足...


0

就我而言,我的VB Web窗体项目解决方案引用了C#UserControl。VB项目和CS项目都具有对同一服务的服务引用。该引用出现在VB项目中的“服务引用”下和CS(框架)项目中的“连接的服务”组下。

为了在VB Web窗体项目中更新服务引用(即,使Reference.vb文件不为空),我需要删除CS项目,然后更新VB服务引用,然后将CS项目添加回解决方案。


0

跟着这些步骤:

  1. 删除服务参考
  2. 关闭Visual Studio
  3. 删除/ Bin和/ Obj文件夹。
  4. 打开Visual Studio。
  5. 添加服务参考。
  6. 别客气 :)

添加服务时,这些文件夹中似乎保留了一些引用,从而在自动生成代码期间导致错误。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.