C# 有时添加 WCF 服务引用会生成一个空的 reference.cs
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1408509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sometimes adding a WCF Service Reference generates an empty reference.cs
提问by Matt
Sometimes adding a WCF Service Reference generates an empty reference.cs and I cannot reference the service anywhere in the project.
有时添加 WCF 服务引用会生成一个空的 reference.cs,我无法在项目中的任何位置引用该服务。
Has anyone encountered this?
有没有人遇到过这个?
采纳答案by Anderson Imes
Generally I find that it's a code-gen issue and mostof the time it's because I've got a type name conflict it couldn't resolve.
一般来说,我发现这是一个代码生成问题,大多数时候是因为我遇到了无法解决的类型名称冲突。
If you right-click on your service reference and click configure and uncheck"Reuse Types in Referenced Assemblies"it'll likely resolve the issue.
如果您右键单击您的服务引用并单击配置并取消选中“Reuse Types in Referenced Assemblies”,它可能会解决问题。
If you were using some aspect of this feature, you might need to make sure your names are cleaned up.
如果您正在使用此功能的某些方面,您可能需要确保您的名字被清理干净。
回答by John Saunders
When this happens, look in the Errors window and the Output window to see if there are any error messages. If that doesn't help, try running svcutil.exe
manually, and see if there are any error messages.
发生这种情况时,请查看“错误”窗口和“输出”窗口以查看是否有任何错误消息。如果这没有帮助,请尝试svcutil.exe
手动运行,看看是否有任何错误消息。
回答by dblood
As the accepted answer points out, a type reference issue when reusing types is probably the culprit. I found when you cannot easily determine the issue then using svcutil.exe command line will help you reveal the underlying problem (as John Saunders points out).
正如公认的答案所指出的,重用类型时的类型引用问题可能是罪魁祸首。我发现当您无法轻松确定问题时,使用 svcutil.exe 命令行将帮助您揭示潜在问题(正如 John Saunders 指出的那样)。
As an enhancement here is a quick example of using svcutil.
作为增强,这里是一个使用 svcutil 的快速示例。
svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:\MyCode\MyAssembly\bin\debug\MyAssembly.dll"
Where:
在哪里:
- /t:code generates the code from given url
- /d: to specify the directory for the output
- /r: to specify a reference assembly
- /t:code 从给定的 url 生成代码
- /d:指定输出目录
- /r: 指定引用程序集
Full svcutil command line reference here: http://msdn.microsoft.com/en-us/library/aa347733.aspx
完整的 svcutil 命令行参考:http: //msdn.microsoft.com/en-us/library/aa347733.aspx
Once you run svcutil, you should see the exception being thrown by the import. You may receive this type of message about one of your types: "referenced type cannot be used since it does not match imported DataContract".
运行 svcutil 后,您应该会看到导入引发的异常。您可能会收到有关您的类型之一的此类消息:“无法使用引用类型,因为它与导入的 DataContract 不匹配”。
This could simply be as specified in that there is a difference in one of the types in the referenced assembly from what was generated in the DataContract for the service. In my case, the service I was importing had newer, updated types from what I had in the shared assembly. This was not readily apparent because the type mentioned in the exception appeared to be the same. What was different was one of the nested complex types used by the type.
这可以简单地按照指定的方式进行,因为引用程序集中的类型之一与在服务的 DataContract 中生成的类型存在差异。就我而言,我正在导入的服务具有更新的、更新的类型,这些类型来自我在共享程序集中的类型。这不是很明显,因为例外中提到的类型似乎是相同的。不同的是该类型使用的嵌套复杂类型之一。
There are other more complex scenarios that may trigger this type of exception and resulting blank reference.cs. Here is one example.
还有其他更复杂的场景可能会触发此类异常并导致引用.cs 空白。这是一个例子。
If you are experiencing this issue and you are not using generic types in your data contracts nor are you using IsReference = true, then I recommend verifying for certain that your shared types are exactly the same on your client and server. Otherwise, you will likely run into this issue.
如果您遇到此问题并且您没有在数据协定中使用泛型类型,也没有使用 IsReference = true,那么我建议您确认您的共享类型在您的客户端和服务器上是否完全相同。否则,您很可能会遇到此问题。
回答by user1353936
I have found this to occur commonly whenever I add a reference, remove it, and then re-add a service with the same name. The type conflicts appear to be caused by the old files remaining somewhere that Visual Studio can still see. All I need to do to fix it, is a clean before adding the new reference.
我发现这种情况在我添加引用、删除引用,然后重新添加同名服务时很常见。类型冲突似乎是由保留在 Visual Studio 仍然可以看到的地方的旧文件引起的。我需要做的就是在添加新引用之前清理它。
- Remove the service reference having issues.
- Click on the project name in the Solution Explorerto highlight the project.
- Right-click on the project reference.
- Near the top of the context list, click the Cleanitem.
- Add your service reference as you normally would.
- 删除有问题的服务引用。
- 单击解决方案资源管理器中的项目名称以突出显示该项目。
- 右键单击项目引用。
- 在上下文列表顶部附近,单击清理项目。
- 像往常一样添加您的服务引用。
Hope this helps.
希望这可以帮助。
回答by Matt Kane
I've been bashing my head for a whole day with this exact problem. I've just fixed it. Here's how...
我一整天都在为这个确切的问题而头疼。我刚刚修好了。就是这样...
The service hadto run over SSL (i.e. it's at https://mydomain.com/MyService.svc)
该服务必须通过 SSL 运行(即它位于https://mydomain.com/MyService.svc)
Adding a service reference to the WCF service on a development server worked just fine.
在开发服务器上添加对 WCF 服务的服务引用工作正常。
Deploying the exactsame build of the WCF service on the live production server, then switching to the client application and configuring the service reference to point to the live service displayed no errors but the app wouldn't build: It turns out that the service reference's Reference.cs file was completely empty! Updating the service reference made no difference. Cleaning the solution didn't help. Restarting VS2010 made no difference. Creating a new blank solution, starting a console project and adding a service reference to the live service exhibited exactly the same problem.
在实时生产服务器上部署完全相同的 WCF 服务构建,然后切换到客户端应用程序并将服务引用配置为指向实时服务没有显示任何错误,但应用程序不会构建:结果是服务引用的Reference.cs 文件完全是空的!更新服务参考没有区别。清洁溶液没有帮助。重新启动 VS2010 没有任何区别。创建一个新的空白解决方案,启动一个控制台项目并添加一个对实时服务的服务引用,表现出完全相同的问题。
I didn't think it was due to conflicting types or anything, but what the heck - I reconfigured the WCF service reference by unchecking "Reuse types in all referenced assemblies". No joy; I put the check mark back.
我不认为这是由于类型冲突或任何原因造成的,但是到底是什么 - 我通过取消选中“在所有引用的程序集中重用类型”来重新配置 WCF 服务引用。没有快乐;我把复选标记放回去。
Next step was to try svcutilon the reference URL to see if that would help uncover the problem. Here's the command:
下一步是在参考 URL 上尝试svcutil以查看这是否有助于发现问题。这是命令:
svcutil /t:code https://mydomain.com/MyService.svc /d:D:\test
This produced the following:
这产生了以下内容:
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.
That had me completely stumped. Despite heavy googling and getting really rather cross, and reconsidering a career as a bus driver, I finally considered why it worked OK on the development box. Could it be an IIS configuration issue?
这让我完全难住了。尽管进行了大量的谷歌搜索并且变得非常生气,并重新考虑了作为公交车司机的职业,但我终于考虑了为什么它在开发盒上运行良好。会不会是 IIS 配置问题?
I remoted simultaneously into both the development and live boxes, and on each I fired up the IIS Manager (running IIS 7.5). Next, I went through each configuration setting on each box, comparing the values on each server.
我同时远程进入开发盒和实时盒,并在每个盒中启动 IIS 管理器(运行 IIS 7.5)。接下来,我检查了每个盒子上的每个配置设置,比较了每个服务器上的值。
And there's the problem: Under "SSL Settings" for the site, make sure "Require SSL" is checked, and check the Client Certificates radio button for "Accept". Problem fixed!
还有一个问题:在站点的“SSL 设置”下,确保选中“需要 SSL”,并选中“接受”的客户端证书单选按钮。问题已解决!
回答by Jon Person
If you recently added a collection to your project when this started to occur, the problem may be caused by two collections which have the same CollectionDataContractattribute:
如果您最近在项目开始时添加了一个集合,则问题可能是由具有相同CollectionDataContract属性的两个集合引起的:
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="AItems", ItemName="A")] // Wrong
public class CollectionB : List<B> { }
I fixed the error by sweeping through my project and ensuring that every Nameand ItemNameattribute was unique:
我通过扫描我的项目并确保每个Name和ItemName属性都是唯一的来修复错误:
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="BItems", ItemName="B")] // Corrected
public class CollectionB : List<B> { }
Then I refreshed the service reference and everything worked again.
然后我刷新了服务参考,一切又正常了。
回答by sagesky36
My issue was that I left the "mex" onto the end of my web service link.
我的问题是我将“ mex”留在了我的网络服务链接的末尾。
Instead of "http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex"
而不是“ http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex”
Use "http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc"
使用“ http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc”
回答by Simon_Weaver
I had this problem with a Silverlight 5 upgraded from a previous version.
我在从以前的版本升级的 Silverlight 5 上遇到了这个问题。
Even re-adding the service reference still gave me an empty Reference.cs
即使重新添加服务引用仍然给了我一个空的 Reference.cs
I ended up having to create a brand new project and re-creating the service reference. This is something to try if you've spent more than about half an hour on this. Even if you're determined to fix the original project you may want to try this just to see what happens and then work backwards to try to fix the problem.
我最终不得不创建一个全新的项目并重新创建服务引用。如果您在这方面花费了大约半小时以上,那么可以尝试一下。即使您决定修复原始项目,您也可能想尝试一下,看看会发生什么,然后倒退以尝试解决问题。
I never did figure out exactly what the problem was - but possibly something in the .csproj file wasn't upgraded or some setting went wrong.
我从来没有弄清楚到底是什么问题 - 但可能 .csproj 文件中的某些内容没有升级或某些设置出错。
回答by atlaste
As @dblood points out, the main pain is in the DataContractSerializer, that doens't correctly re-use the types. There are already some answers here so I'll start by adding some pro's and cons about these:
正如@dblood 指出的那样,主要的痛苦在于 DataContractSerializer,它没有正确地重用类型。这里已经有一些答案,所以我将首先添加一些关于这些的优点和缺点:
- The 'IsReference' flag causes a lot of trouble, but removing it isn't always the answer (specifically: in situations with recursion).
- The underlying issue is that the data contract is somehow not the same as the type names, even though they sometimes are (huh? Yes, you read that right!). Apparently the serializer is quite picky and it's very hard to find the real issue.
- Removing the 'references checks' from the 'Configure service reference' works, but leaves you with a multiple implementations. However, I often reuse SOAP interfaces across DLL's. Also, in most mature SOA's that I know, multiple services interfaces implement and extend the same interface classes. Removing 'use referenced types' checks results in a situation where you cannot simply pass objects around anymore.
- 'IsReference' 标志会引起很多麻烦,但删除它并不总是答案(特别是:在递归的情况下)。
- 潜在的问题是数据契约在某种程度上与类型名称不同,即使它们有时是(嗯?是的,你没看错!)。显然,序列化程序非常挑剔,很难找到真正的问题。
- 从“配置服务引用”中删除“引用检查”是可行的,但会给您留下多个实现。但是,我经常在 DLL 中重用 SOAP 接口。此外,在我所知的大多数成熟的 SOA 中,多个服务接口实现和扩展相同的接口类。删除“使用引用类型”检查会导致您无法再简单地传递对象。
Fortunately, if you are in control of your service, there is a simple solution that solves all these issues. This means you can still re-use service interfaces across DLL's - which is IMO a must-have for a proper solution. This is how the solution works:
幸运的是,如果您可以控制自己的服务,那么有一个简单的解决方案可以解决所有这些问题。这意味着您仍然可以跨 DLL 重用服务接口 - 这是 IMO 正确解决方案的必备条件。这是解决方案的工作原理:
- Create a separate interface DLL. In that DLL, include all DataContract and ServiceContract's; put ServiceContract's on your interfaces.
- Derive the server implementation from the interface.
Use the same DLL to construct the client using your favorite method. For example (IMyInterface is the service contract interface):
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();
- 创建一个单独的接口 DLL。在该 DLL 中,包括所有 DataContract 和 ServiceContract;将 ServiceContract 放在您的接口上。
- 从接口派生服务器实现。
使用相同的 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();
In other words: Don't use the 'add service reference' functionality, but force WCF to use the (correct) service types by bypassing the proxy generation. After all, you already have these classes.
换句话说:不要使用“添加服务引用”功能,而是通过绕过代理生成来强制 WCF 使用(正确的)服务类型。毕竟,您已经拥有这些课程。
Pro's:
亲:
- You bypass the svcutil.exe process, which means you don't have any IsReference issues
- DataContract types and names are correct by definition; after all, both server and client use the very same definition.
- If you extend the API or use types from another DLL, (1) and (2) still hold, so you won't run in any trouble there.
- 您绕过了 svcutil.exe 进程,这意味着您没有任何 IsReference 问题
- 根据定义,DataContract 类型和名称是正确的;毕竟,服务器和客户端都使用相同的定义。
- 如果您扩展 API 或使用来自另一个 DLL 的类型,(1) 和 (2) 仍然成立,因此您不会在那里遇到任何麻烦。
Cons:
缺点:
- A-sync methods are a pain, since you don't generate an a-sync proxy. As a result, I wouldn't recommend doing this in Silverlight applications.
- A-sync 方法很麻烦,因为您不生成 a-sync 代理。因此,我不建议在 Silverlight 应用程序中执行此操作。
回答by JoshuaLawrence
The technique that worked for me in my case, after reading these answers to no avail, was simply to comment out all of my contract, and uncomment bits until it doesn't work anymore, in a binary search fashion. That narrows down the offending bit of code.
在阅读这些答案无济于事后,在我的案例中对我有用的技术只是以二进制搜索的方式注释掉我的所有合同,并取消注释直到它不再起作用为止。这缩小了有问题的代码位。
Then you just have to guess what's wrong with that code.
然后你只需要猜测该代码有什么问题。
Some error feedback in the tool would have helped, of course.
当然,工具中的一些错误反馈会有所帮助。
I am writing a web service contract. I had a placeholder enum with no members. That's OK. But if I use it in a property of another class, and re-use the contract dll on the client, the codegen explodes with no error message. Running svcutil.exe didn't help, it just failed to output a cs file without mentioning why.
我正在编写网络服务合同。我有一个没有成员的占位符枚举。没关系。但是,如果我在另一个类的属性中使用它,并在客户端上重新使用合同 dll,则代码生成器会爆炸而没有错误消息。运行 svcutil.exe 没有帮助,它只是无法输出 cs 文件而没有提及原因。