有时添加WCF服务引用会生成一个空的reference.cs
有时添加WCF服务引用会生成一个空的reference.cs,我无法在项目中的任何位置引用该服务。
有没有人遇到过这个?
一般来说,我发现这是一个codegen问题, 大部分时间是因为我有一个types名称冲突,它无法解决。
如果右键单击服务引用并单击“configuration”,并取消选中 “在引用的程序集中重用types”,则可能会解决该问题。
如果你正在使用这个function的某个方面,你可能需要确保你的名字被清理。
正如接受的答案所指出的,重用types时的types引用问题可能是罪魁祸首。 我发现,当你不能轻易确定问题,然后使用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,你应该看到导入引发的exception。 您可能会收到有关您的某个types的此类消息:“引用types由于与导入的DataContract不匹配而无法使用”。
这可以简单地按照指定的方式进行,因为引用程序集中的某个types与服务的DataContract中生成的types有所不同。 在我的情况下,我正在导入的服务有更新的,更新的types从我在共享程序集中。 这是不明显的,因为在例外中提到的types似乎是相同的。 不同的是这种types使用的嵌套复合types之一。
还有其他更复杂的情况可能会触发这种types的exception,并导致空白reference.cs。 这是一个例子 。
如果您遇到此问题,并且您没有在数据合同中使用genericstypes,也不使用IsReference = true,那么我build议您确保您的共享types在客户端和服务器上完全相同。 否则,你可能会遇到这个问题。
我一直在这个问题上抨击我的头脑。 我刚修好了。 就是这样…
该服务必须通过SSL运行(即在https://mydomain.com/MyService.svc )
在开发服务器上添加服务引用到WCF服务工作得很好。
在生产服务器上部署完全相同的WCF服务版本,然后切换到客户端应用程序,并将服务引用configuration为指向实时服务显示没有错误,但应用程序不会生成:事实certificate,服务引用Reference.cs文件是完全空的! 更新服务参考没有任何区别。 清理解决scheme没有帮助。 重新启动VS2010没有任何区别。 创build一个新的空白解决scheme,启动一个控制台项目,并添加一个服务参考到现场服务展示完全相同的问题。
我不认为这是由于冲突types或任何东西,但什么 – 我重新configurationWCF服务引用取消选中“在所有引用的程序集重用types”。 没有喜乐; 我把复选标记放回去。
下一步是在参考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.
这让我彻底难倒了。 尽pipe大量的使用googlesearch,并且真正相互交叉,重新考虑了一个公交车司机的职业生涯,我终于考虑了为什么它在发展箱上运行良好。 它可能是一个IISconfiguration问题?
我同时远程进入开发框和活动框,每次启动IISpipe理器(运行IIS 7.5)。 接下来,我浏览了每个框上的每个configuration设置,比较每个服务器上的值。
并且存在问题:在站点的“SSL设置”下,确保选中“需要SSL”,然后检查客户证书单选button“接受”。 问题修复了!
发生这种情况时,请查看“错误”窗口和“输出”窗口,查看是否有任何错误消息。 如果这没有帮助,请尝试手动运行svcutil.exe
,并查看是否有任何错误消息。
当我添加一个引用,删除它,然后重新添加一个具有相同名称的服务时,我发现这种情况通常会发生。 types冲突似乎是由旧文件保留在Visual Studio仍然可以看到的地方。 所有我需要做的修复它,是一个干净的,添加新的参考。
- 删除有问题的服务参考。
- 在解决scheme资源pipe理器中单击项目名称以突出显示该项目。
- 用鼠标右键单击项目引用。
- 在上下文列表顶部附近,单击清理项目。
- 像平常一样添加您的服务参考。
希望这可以帮助。
我从以前的版本升级了Silverlight 5时遇到了这个问题。
即使重新添加服务引用仍然给我一个空的Reference.cs
我最终不得不创build一个全新的项目并重新创build服务参考。 如果你花了超过半小时左右的时间,这是一件可以尝试的事情。 即使你决定修复原来的项目,你也可以尝试一下,看看会发生什么,然后回去尝试解决问题。
我从来没有弄清楚到底是什么问题 – 但可能在.csproj文件中没有升级或某些设置出错。
如果最近在项目开始发生时向项目添加了一个集合,则问题可能由两个具有相同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> { }
然后我刷新服务参考,一切都再次运作。
我的问题是,我离开了“ mex ”到我的networking服务链接的末尾。
而不是“ http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex ”
使用“ http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc ”
在我看来这些解决scheme无济于事的技术对我来说很简单,就是把我的所有合同注释掉,并且用二进制search的方式取消注释,直到它不再起作用。 这缩小了代码的有害位。
那么你只需要猜测那个代码有什么问题。
当然,这个工具中的一些错误反馈会有所帮助。
我正在写一个Web服务合同。 我有一个没有成员的占位符枚举。 没关系。 但是,如果我在另一个类的属性中使用它,并重新使用客户端上的合同DLL CodeGo.net,codegen爆炸没有错误信息。 运行svcutil.exe没有帮助,它只是没有提到为什么输出一个CSV文件。
下面是这里没有列出的,这是我采用的解决scheme(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
文件,我将其包含在我的项目中并使用该服务实例化。
正如@dblood指出的那样,主要的困难是DataContractSerializer,它不能正确地重用这些types。 这里已经有了一些答案,所以我将开始添加一些赞成和反对这些:
- 'IsReference'标志会引起很多麻烦,但是删除它并不总是答案(特别是:在recursion情况下)。
- 根本的问题是,数据契约与types名称不太一样,即使它们有时是(呃,是的,你读得对! 显然,序列化器是相当挑剔的,很难find真正的问题。
- 从“configuration服务引用”中删除“引用检查”可以工作,但会给您留下多个实现。 不过,我经常在DLL中重复使用SOAP接口。 而且,在我所知道的大多数成熟的SOA中,多个服务接口实现和扩展相同的接口类。 删除“使用引用types”检查会导致无法简单地传递对象的情况。
幸运的是,如果您掌控了您的服务,那么有一个简单的解决scheme可以解决所有这些问题。 这意味着您仍然可以在DLL之间重新使用服务接口 – 这是IMO必备的解决scheme。 这就是解决scheme的工作原理:
- 创build一个单独的接口DLL。 在该DLL中,包含所有DataContract和ServiceContract的; 把ServiceContract放在你的界面上。
- 从接口派生服务器实现。
-
使用相同的DLL来构build客户端使用您最喜爱的方法。 例如(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();
换句话说: 不要使用“添加服务引用”function ,而是强制WCF绕过代理生成来使用(正确的)服务types。 毕竟,你已经有了这些课程。
Pro的:
- 您绕过了svcutil.exe进程,这意味着您没有任何IsReference问题
- DataContracttypes和名称按照定义是正确的; 毕竟,服务器和客户端都使用相同的定义。
- 如果您扩展API或使用其他DLL中的types,则(1)和(2)仍然成立,所以您不会在那里遇到任何麻烦。
缺点:
- 由于您不生成同步代理,因此同步方法很痛苦。 所以,我不会推荐在Silverlight应用程序中这样做。
在处理双方的项目引用(服务项目和引用该服务的项目)时,我也遇到了服务引用中断的问题。 如果被引用的项目的.dll例如被称为“Contoso.Development.Common”,但是项目名称简单地缩写为“Common”,那么对该项目的项目引用也被命名为“Common”。 然而,该服务期望引用“Contoso.Development.Common”来parsing类(如果在服务引用选项中激活了该选项)。
因此,与资源pipe理器,我打开引用该服务和“共同”项目的项目文件夹。 在那里我用记事本编辑VS项目文件(.csproj)。 search引用项目的名称(在本例中为“Common.csproj”),您将快速find代表项目引用的configuration条目。
我变了
<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以外。 点击重新加载button。
这样做之后,添加和更新服务引用正常工作。
希望这也能帮助别人。
问候MH
我昨天在开发时遇到过类似的问题。 我发现我在两个不同版本的合同中使用了相同的命名空间。
例如版本4和版本5我们有两个版本的合同。 我已经复制了版本4的所有合同,并将所有的命名空间从版本4重命名为版本5。 在这样做的时候,我忘记了在其中一个文件中将命名空间从v4重命名为v5。 由于命名空间冲突,Reference.cs文件是空的。
由于在生成服务引用时不会收到任何错误消息,因此此问题很难排除故障。 要确定这个问题,我会手动validation所有创build的新文件。 还有其他方法可以解决这个问题。 在进行其他select之前,这是您应该执行的第一步。