有时,添加WCF服务引用会生成一个空的reference.cs

时间:2009-09-11 00:57:44

标签: c# .net wcf

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

有没有人遇到过这个?

17 个答案:

答案 0 :(得分:368)

一般来说,我发现这是一个代码生成问题和大多数的时间,因为我有一个无法解决的类型名称冲突。

如果右键单击服务引用并单击“配置”并取消选中 “重用参考程序集中的类型”,则可能会解决此问题。

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

答案 1 :(得分:36)

正如接受的答案所指出的,重用类型时的类型引用问题可能是罪魁祸首。我发现当你无法轻易确定问题时,使用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:代码生成来自给定网址的代码
  • / d:指定输出目录
  • / r:指定参考程序集

此处的完整svcutil命令行参考:http://msdn.microsoft.com/en-us/library/aa347733.aspx

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

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

还有其他更复杂的方案可能会触发此类异常并导致空白的reference.cs。 Here is one example

如果您遇到此问题且未在数据合同中使用泛型类型,也未使用IsReference = true,那么我建议您确认您的共享类型在客户端和服务器上完全相同。否则,您可能会遇到此问题。

答案 2 :(得分:11)

我一直在用这个确切的问题抨击我的头一整天。我刚修好了。这是怎么......

服务通过SSL运行(即它位于https://mydomain.com/MyService.svc

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

在实时生产服务器上部署完全相同版本的WCF服务,然后切换到客户端应用程序并配置服务引用以指向实时服务,但没有显示任何错误,但应用程序不会t build:事实证明服务引用的Reference.cs文件是完全空的!更新服务引用没有任何区别。清洁解决方案没有帮助。重启VS2010没有任何区别。创建一个新的空白解决方案,启动一个控制台项目并向实时服务添加服务引用表现出完全相同的问题。

我认为这不是由于冲突的类型或任何东西,而是什么 - 我通过取消选中“在所有引用的程序集中重用类型”来重新配置WCF服务引用。没有快乐;我把复选标记放回去了。

下一步是在参考网址上尝试 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”,并选中“客户证书”单选按钮以“接受”。问题已解决!

答案 3 :(得分:9)

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

答案 4 :(得分:4)

我发现每当我添加引用,删除它,然后重新添加具有相同名称的服务时,这种情况就会发生。类型冲突似乎是由Visual Studio仍然可以看到的旧文件引起的。我需要做的就是修复它,在添加新引用之前是干净的。

  1. 删除有问题的服务参考。
  2. 单击解决方案资源管理器中的项目名称以突出显示该项目。
  3. 右键单击项目参考。
  4. 在上下文列表的顶部附近,单击清除项。
  5. 像往常一样添加服务引用。
  6. 希望这有帮助。

答案 5 :(得分:3)

我从先前版本升级的Silverlight 5出现了这个问题。

即使重新添加服务引用仍然给了我一个空的Reference.cs

我最终不得不创建一个全新的项目并重新创建服务参考。 如果你花了超过半小时就可以尝试这个。即使您决定修复原始项目,您也可以尝试这样做,看看会发生什么,然后向后工作以尝试解决问题。

我从未弄清楚问题的确切原因 - 但是.csproj文件中的某些内容未升级或某些设置出错。

答案 6 :(得分:1)

如果您最近在项目开始时向项目添加了一个集合,则问题可能是由两个具有相同 CollectionDataContract 属性的集合引起的:

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

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

我通过扫描项目并确保每个名称 ItemName 属性都是唯一的来修复错误:

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

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

然后我刷新了服务引用,一切都恢复了。

答案 7 :(得分:1)

我的问题是我将“ mex ”留在我的网络服务链接的末尾。

而不是“http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex

使用“http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc

答案 8 :(得分:1)

在我的案例中,对我来说有用的技术,在阅读这些答案后无济于事,只是简单地评论我的所有合同,并以二进制搜索方式取消注释,直到它不再起作用。这缩小了令人讨厌的代码。

然后你只需要猜出该代码有什么问题。

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

我正在写一份网络服务合同。我有一个没有成员的占位符枚举。没关系。但是如果我在另一个类的属性中使用它,并在客户端上重用合约dll,则codegen会爆炸而没有错误消息。运行svcutil.exe没有帮助,它只是输出一个cs文件而没有提到原因。

答案 9 :(得分:1)

这里没有列出以下内容,这是我采用的解决方案(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文件,我将其包含在我的项目中并实例化以使用该服务

答案 10 :(得分:0)

请按照以下步骤操作:

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

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

答案 11 :(得分:0)

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

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

答案 12 :(得分:0)

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

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

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

答案 13 :(得分:0)

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

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

答案 14 :(得分:0)

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

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

由于您在生成服务引用时未收到任何错误消息,因此很难排除此问题。要确定此问题,我手动验证我创建的所有新文件。还有其他方法可以解决这个问题。这是您在选择其他选项之前应该执行的第一步。

答案 15 :(得分:0)

在双方使用项目引用(服务项目和引用服务的项目)时,我也遇到了服务引用中断的问题。 例如,如果引用的项目的.dll被调用&#34; Contoso.Development.Common&#34;,但是项目名称简单地缩短为&#34; Common&#34;,项目对此项目的引用也是名为&#34; Common&#34;。但是,该服务需要参考&#34; Contoso.Development.Common&#34;用于解析类(如果在服务引用选项中激活此选项)。

因此,对于资源管理器,我打开了引用该服务的项目文件夹和&#34; Common&#34; -project。在那里我使用记事本编辑VS项目文件(.csproj)。 搜索引用项目的名称(在此示例中为&#34; Common.csproj&#34;),您将快速找到表示项目引用的配置条目。

我改变了

<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

答案 16 :(得分: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();
    
  4. 换句话说:不要使用“添加服务引用”功能,而是强制WCF绕过代理生成来使用(正确的)服务类型。毕竟,你已经有了这些课程。

    Pro的:

    1. 绕过svcutil.exe进程,这意味着您没有任何IsReference问题
    2. 根据定义,DataContract类型和名称是正确的;毕竟,服务器和客户端都使用相同的定义。
    3. 如果您扩展API或使用其他DLL中的类型,(1)和(2)仍然存在,那么您将不会遇到任何麻烦。
    4. 缺点:

      1. A-sync方法很痛苦,因为您不生成同步代理。因此,我不建议在Silverlight应用程序中执行此操作。