代码之家  ›  专栏  ›  技术社区  ›  Matt

有时添加wcf服务引用会生成空引用.cs

  •  151
  • Matt  · 技术社区  · 15 年前

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

    有人遇到过这个吗?

    15 回复  |  直到 6 年前
        1
  •  367
  •   stefan    6 年前

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

    如果右键单击服务引用并单击配置和 取消检查 “重用引用的程序集中的类型” 它很可能会解决这个问题。

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

        2
  •  36
  •   dblood    13 年前

    正如公认的答案所指出的,重用类型时的类型引用问题可能是罪魁祸首。我发现,当您无法轻松确定问题时,使用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/en-us/library/aa347733.aspx

    运行svcutil之后,应该会看到导入正在引发异常。您可能会收到关于某个类型的此类消息:“引用的类型与导入的DataContract不匹配,因此无法使用”。

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

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

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

        3
  •  11
  •   Matt Kane    12 年前

    我为这个问题苦恼了一整天。我刚修好。以下是如何…

    服务 运行ssl(即 https://mydomain.com/MyService.svc )

    在开发服务器上添加对WCF服务的服务引用工作得很好。

    部署 准确的 同一版本的wcf服务在实时生产服务器上,然后切换到客户端应用程序,配置服务引用指向实时服务,没有显示任何错误,但应用程序不会生成:原来服务引用的reference.cs文件是完全空的!更新服务引用没有区别。清洗溶液没有帮助。重启VS2010没有什么不同。创建一个新的空白解决方案,启动一个控制台项目,并向实时服务添加一个服务引用,都显示了完全相同的问题。

    我不认为这是由于类型冲突或其他原因造成的,但我通过取消选中“在所有引用的程序集中重用类型”,重新配置了WCF服务引用。不高兴,我把支票打回去了。

    下一步是尝试 斯库蒂尔 在参考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”,并检查了“接受”的客户机证书单选按钮。问题解决了!

        4
  •  9
  •   John Saunders    15 年前

    发生这种情况时,请在错误窗口和输出窗口中查看是否有任何错误消息。如果这不起作用,试着跑步 svcutil.exe 手动,并查看是否有任何错误消息。

        5
  •  4
  •   user1353936    12 年前

    我发现,每当添加引用、删除引用,然后重新添加同名服务时,都会出现这种情况。类型冲突似乎是由Visual Studio仍能看到的旧文件所导致的。我需要做的就是在添加新引用之前清除它。

    1. 删除有问题的服务引用。
    2. 单击中的项目名称 解决方案管理器 突出显示项目。
    3. 右键单击项目引用。
    4. 在上下文列表顶部附近,单击 干净的 项目。
    5. 像平常一样添加服务引用。

    希望这有帮助。

        6
  •  3
  •   Simon_Weaver    11 年前

    我在从以前版本升级的Silverlight5上遇到了这个问题。

    即使重新添加服务引用,仍然会给我一个空引用.cs

    最后我不得不创建一个全新的项目,并重新创建服务引用。 如果你花了半个多小时在这上面,这是一件值得尝试的事情。即使您决定修复原始项目,您也可能希望尝试这样做只是为了看看会发生什么,然后向后工作以尝试修复问题。

    我从来没有弄清楚到底是什么问题-但可能是.csproj文件中的某些内容没有升级或某些设置出错。

        7
  •  1
  •   Jon Person    11 年前

    如果您最近在项目中添加了一个集合,而此情况开始出现时,问题可能是由两个具有相同集合的集合引起的。 集合数据合同 属性:

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

    我通过彻底检查我的项目并确保 名字 项目名称 属性唯一:

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

    然后我刷新了服务引用,一切都重新工作了。

        8
  •  1
  •   sagesky36    11 年前

    我的问题是我离开了 墨西哥人 “在我的Web服务链接的末尾。

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

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

        9
  •  1
  •   JoshuaLawrence    9 年前

    在我的案例中,在阅读了这些答案之后,我所使用的技术是简单地注释掉我的所有契约,并取消注释位,直到它不再工作为止,以二进制搜索的方式。这就缩小了有问题的代码范围。

    然后你只需猜测代码有什么问题。

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

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

        10
  •  1
  •   Community dbr    7 年前

    下面没有列出,这是我采用的解决方案(svcutils在查看错误消息时很有用)。但是,我得到的错误是 wrapper type message cannot be projected as a data contract type since it has multiple namespaces . 意思是,我跟着这条线索,学到了 wsdl.exe 通过 this 帖子)。

    在我的例子中,只需运行WSDL[ 我的ASMX服务地址 ]生成了一个无问题的 .cs 文件,我将其包含在我的项目中并实例以使用该服务。

        11
  •  0
  •   atlaste    11 年前

    正如@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使用(正确)服务类型。毕竟,你已经有了这些课程。

    Pro的:

    1. 您绕过svcutil.exe进程,这意味着您没有任何ISreference问题。
    2. 根据定义,DataContract类型和名称是正确的;毕竟,服务器和客户机都使用相同的定义。
    3. 如果扩展API或使用另一个dll中的类型,(1)和(2)仍然保持不变,因此不会在那里运行任何问题。

    欺骗:

    1. A-Sync方法很麻烦,因为您不生成A-Sync代理。因此,我不建议在Silverlight应用程序中这样做。
        12
  •  0
  •   Martype    9 年前

    我在处理两边的项目引用(服务项目和引用服务的项目)时也遇到了中断服务引用的问题。 例如,如果引用项目的.dll被称为“contoso.development.common”,但项目名称被简单地缩短为“common”,则对该项目的项目引用也只被命名为“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.there,您将被要求重新加载项目,因为它已在vs.之外被修改。单击重新加载按钮。

    在这样做之后,添加和更新服务引用就如预期的那样工作。

    希望这也能帮助别人。

    当做 MH公司

        13
  •  0
  •   arif.khan.b    8 年前

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

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

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

        14
  •  0
  •   Ziggler    6 年前

    多亏了上面的约翰·桑德斯的文章,我才有了一个进入错误窗口的想法。我一整天都在装袋,我在查看输出窗口是否有任何错误。

    在我的案件中,罪犯是可以被电子化的。我有一个DataContract类,其DataMember属性属于异常类型。不能有任何类型的datamember具有ISerializable关键字。在这个例外情况下,只要我把它移除,一切都会像一个魔咒一样工作。

        15
  •  0
  •   Platedslicer    6 年前

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

    在我的例子中,基本原因似乎是一个具有datacontract属性的枚举类型,但其成员没有用enummember属性标记。问题类 斯库蒂尔 指向具有具有该枚举类型的属性。

    这将更适合作为对dblood答案的评论,但没有足够的代表来做这件事…