服务引用不生成客户端类型

Posted

技术标签:

【中文标题】服务引用不生成客户端类型【英文标题】:Service reference not generating client types 【发布时间】:2011-03-01 07:44:34 【问题描述】:

我正在尝试通过添加服务引用来使用类库中的 WCF 服务。在其中一个类库中,它被正确使用,我可以访问客户端类型以生成代理。然而,在我的第二个类库中(甚至在控制台测试应用程序中),当我添加相同的服务引用时,它只公开了合同操作中涉及的类型,而不是我生成代理的客户端类型。

例如Endpoint 暴露了 2 个服务 - ISvc1 和 ISvc2。当我在第一个类库中添加对此端点的服务引用时,我得到 ISvc1Client 和 f ISvc2Client 来生成代理,以便使用通过这两个合同公开的操作。除了这些客户端之外,服务引用还公开了操作中涉及的类型,例如(类型 1、类型 2 等),这就是我需要的。但是,当我尝试在另一个控制台应用程序或类库中添加对相同端点的服务引用时,只有 Type 1、Type 2 等被暴露,而不是 ISvc1Client 和 ISvc2Client,因为我无法生成代理来访问我需要的操作。我无法确定为什么服务引用会在一个类库中正确生成,而在另一个类库或测试控制台应用程序中却没有。

【问题讨论】:

我不太明白,你是说第一个创建服务引用的应用程序获取客户端对象,但后续的没有?这真的没有意义,你能澄清一下,和/或发布一些代码吗? 【参考方案1】:

您可能选择了Reuse types in specified reference assemblies,但没有选择非常重要的mscorlib 库。

首先单击解决方案资源管理器顶部的“显示所有文件”,以便展开服务参考。

找到Reference.cs 文件并打开它。 在源代码中搜索ClientBase 以确保您确实没有生成具有您不期望的名称的客户端。如果您找到它,那么这就是您的服务客户端的名称。

如果没有匹配项,则右键单击服务引用并选择Configure Service Reference

重要的是 mscorlib 是正确生成客户端所必需的。我也喜欢选择 System.Xml.Linq 来获得像 XElement 这样好的 Linq 类,而不是 XmlElement


还是卡住了?

提示:我总是更喜欢创建一个专门的 DLL 仅用于服务引用。如果您需要清除它并重新开始,它会有所帮助,并且它可以避免偶尔出现某些先有鸡还是先有蛋的编译问题。

如果您最终得到半个 References.cs 文件,您可能会“重复使用与您的数据协定不兼容的引用类型”。即您在服务器端添加了数据成员,或更改了现有成员的签名,例如使值类型可选。

1234563在 Explorer 中留意预期尺寸,并将其与您的“最后一次已知良好”尺寸进行比较。

尝试直接从批处理文件运行 SVCUTIL.EXE(记得保存此文件以备下次使用)

在 Visual Studio 命令提示符下最容易做到这一点

示例命令如下,请注意您要从中引用类型的 DLL 的 reference 参数。

svcutil.exe http://dev.example.com/SSWPF.Web/Services/SS.svc /reference:bin\debug\RRStore.Sys.DLL

Detail: An exception was thrown while running a WSDL import extension:

System.ServiceModel.Description.DataContractSerializerMessageContractImporter 错误:引用类型“SS.Sys.ShippingRateInfo,RRStore.Sys,版本=1.0.0.0,文化=中性,PublicKeyToken=null” 命名空间中的数据合同名称为“ShippingRateInfo” 'http://schemas.datacontract.org/2004/07/SS.Sys' 不能 使用,因为它与导入的 DataContract 不匹配。需要排除 此类型来自引用类型。 错误源的 XPath://wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:portType[@name='ISSWCF']

幸运的是,这里的答案很简单,我的类型 ShippingRateInfo 已更改并且我没有更新它。一旦我从服务器上复制了这个类型,一切都编译好了(我选择恢复到 VS 工具)。

【讨论】:

我的问题通过简单地取消选中“在引用的程序集中重用类型”来解决。我的一些课程取消了。 注意:System.ServiceModel 实际上似乎不是必需的。我想它知道它必须使用它 老兄,你是我的新神。我找到了 clientBase 并且类的名称与我的预期不同。非常感谢。【参考方案2】:

真正的答案是,如果您在服务合同上使用 KnownTypeAttribute 序列化类型,则必须在要添加服务引用的项目中包含对您的类型库的引用。

例如,如果您的 wcf 服务序列化类型 System.Drawing.Image,那么使用者项目必须具有对 System.Drawing 的引用。希望这对那里的一些人有所帮助。

【讨论】:

令人讨厌的是它根本不显示任何错误 - 只是生成一些非常截断的代理版本。【参考方案3】:

我遇到过类似的问题,这是由于类型不匹配。因此,我无法在测试项目中生成客户端。我们维护不同版本的合约,在创建新版本时我会引入类型不匹配错误。以下是我的代码场景。

第 1 版合同

[DataContract(Namespace="http://www.exmample.com/v1")]
public enum Fruits

    [EnumMember]
    Apple,
    [EnumMember]
    Orange

第 2 版合同

[DataContract(Namespace="http://www.exmample.com/v1")]
 public enum Fruits
 
    [EnumMember]
    Apple,
    [EnumMember]
    Orange,
    [EnumMember]
    Mango
 

我已经使用 svcutil 命令行实用程序解决了这个问题。 命令

svcutil MyContract.dll

我收到以下错误消息

DataContract for type 'V2.Fruits' cannot be added to DataContractSet since type 'V1.Fruits with the same data contract name 'Fruits' in namespace 'http://www.exmample.com/v1' is already present and the contracts are not equivalent.

我将命名空间从版本 1 更改为版本 2,并且能够在测试项目中生成服务引用。

[DataContract(Namespace="http://www.exmample.com/v2")]
 public enum Fruits
 
    [EnumMember]
    Apple,
    [EnumMember]
    Orange,
    [EnumMember]
    Mango
 

使用 svcutil 这将有助于解决此问题。

【讨论】:

【参考方案4】:

我遇到了同样的问题。原来我的项目是直接引用 DLL 而不是项目引用。因此,即使我的项目有程序集的引用,它也是一个旧版本。一旦我更新了 DLL 并更新了服务引用,一切都恢复了。

【讨论】:

【参考方案5】:

这通常发生在添加您之前添加的服务引用时。在客户端配置中,它仍然具有相关的服务模型。确保从客户端配置中删除服务模型,然后再次尝试重新添加服务引用!

【讨论】:

【参考方案6】:

按照@Kevin 的回答,我添加了对服务项目中引用的所有项目和 DLL 的引用。然后代理生成能够识别/生成所需的类型。

完成后,您甚至可以开始删除一些并重新生成以排除多余的。

【讨论】:

【参考方案7】:

显然,在添加服务引用之前,您必须在项目中添加对 System.Web 的引用。做到了。

【讨论】:

这对我没有帮助。仍然有同样的问题! 这很奇怪,因为我成功生成的代理在 Reference.cs 文件中甚至没有 System.Web...

以上是关于服务引用不生成客户端类型的主要内容,如果未能解决你的问题,请参考以下文章

创建 C# 客户端使用 SOAP 服务而不使用内置的“添加服务引用...”

WCF常见类型不重用

WCF 奇怪的 ReadOnlyDictionary 序列化

WCF服务客户端:内容类型text/html;响应消息的charset=utf-8 与绑定的内容类型不匹配

Webservice客户端动态调用服务端功能方法

添加服务引用创建没有方法的客户端