WCF常见类型不重用

时间:2011-11-27 15:50:02

标签: wcf web-services visual-studio-2010 service-reference

提示:这个问题有很多重复,但没有一个解决方案适合我。

我所拥有的是一个Web服务和一个客户端,它们都引用了共享程序集“DataModel”。我正在使用“添加服务引用...”对话框创建服务代理,并选择“在所有引用的程序集中重用类型”,但它仍然创建新类型而不是重用我的。

  • 它曾经工作,但现在突然间它不再重复使用类型了
  • 在添加服务引用之前引用共享程序集不起作用
  • 重启VS2010没有帮助(我有所有更新)
  • 我试过一个简单的POCO类(只是一个包含整数属性的简单类),也没有运气
  • 删除并重新添加服务引用(或共享程序集引用)没有帮助
  • 仅在“重用指定引用程序集中的类型”中选择共享程序集 - 没有运气
  • svcutil.exe /reference会产生相同的结果

我不知何故以此结束。还有其他解决方案吗?

编辑:我应该补充一点,我只是将我的项目重置为早期提交,无论我使用哪个提交,仍然是同样的问题。我知道它适用于早期的提交!

7 个答案:

答案 0 :(得分:15)

  

在添加服务引用之前引用共享程序集不起作用

您需要这样做,或者至少在添加引用后更新服务引用。

  

删除和重新添加服务引用(或共享程序集引用)没有帮助

你不应该这样做,但我也会尝试过。

为了使“重用”工作,两个项目(客户端和服务)都需要使用相同版本的程序集。您正在引用该项目,这很好 - 我之前因为不同的版本而直接引用程序集时遇到过这种情况。

这里还有其他一些尝试

  • 为您的解决方案打开“Configuration Manager” - 确保将共享程序集配置为构建。
  • 确保您正在为客户端服务使用项目引用 - 如果服务使用旧版本,则使用客户端上的最新程序集将无济于事。
  • 删除项目引用和构建,并期望构建失败 - 如果它没有失败,那么你必须引用别的东西。
  • 手动检查两者服务和客户端中的构建中是否包含最新的“共享程序集” - 检查bin文件夹,检查程序集版本/构建日期。

如果所有其他方法都失败了,强制双方使用同一个对象的最佳方法是完全删除“服务引用”代理并使用ChannelFactory方法。请参阅Simpler Explanation of How to Make Call WCF Service without Adding Service RefVS2010 Advantages of Add Service Reference over direct ClientBase<>。这是我首选的WCF模式,因为它不需要“更新服务引用...”,并删除了所有生成的代理代码。

答案 1 :(得分:11)

我刚刚整整一天试图找出为什么当我在VS2013中添加服务引用时,我的共享dll中的类型没有被重用。事实证明,该服务有几个与序列化有关的问题。我有几个没有EnumMember属性的枚举。我解决问题的方法是尝试以下步骤:

  1. 在我的ServiceContract中注释掉所有操作(使用OperationContract属性修饰的方法)未返回原子类型
  2. 然后在我的客户端项目中更新我的服务参考。我意识到在我的客户端项目中问题已经解决,我可以输入“[MyServiceReferenceName]”。我的类型没有出现在[MyServiceReferenceName]命名空间中。我通过在XML模式浏览器中打开生成的XSD文件来验证这一点,以确定。
  3. 逐步,取消注释在步骤1中注释的方法。然后每次都更新您的服务参考,以查看是否正在恢复类型
  4. 一旦找到导致服务引用无法重用类型的方法,请转到每个类,以获取输入或输出到方法的类型。检查您希望序列化的所有是否使用[DataContract]属性进行修饰。确保使用[DataMember]属性修饰所有字段属性。另外,确保使用[DataContract]修饰枚举,并使用[EnumMember] 修饰每个枚举值。
  5. 我希望这可以帮助那些正在经历这个令人沮丧的过程的人,这个问题不一定与共享的dll有关。使用“添加或更新服务参考”时,我的问题并不是真正的问题。问题在于我的实体(模型)类没有用适当的属性进行修饰,以通知DataContractSerializer序列化这些类型。似乎如果序列化的任何部分失败,添加服务引用会添加所有类型。

答案 2 :(得分:2)

这有点远,但有一种可能性是旧版本的共享dll在GAC中。

尝试使用共享dll,找到缺少类型的dll,然后恢复为创建类型。

答案 3 :(得分:2)

OBJECTCEPTION!

我们最近遇到了同样的问题。我们花了四个小时来搜索问题,但我们最终发现,与拒绝复制的对象在同一个dll中的对象上的枚举与在服务中使用的另一个枚举具有相同的名称,因此它拒绝重用该dll中的任何类型。

建议(溶液): 确保dll中没有其他对象,或者那些对象上的对象,或......等。 与您服务中的名称相同的名称。

答案 4 :(得分:0)

这是一个古老的话题,但是由于我今天遇到了同样的问题,所以我想分享我的修正。

对我来说,问题在于共享程序集已在两个项目(服务和客户端)中正确添加,但是在服务端,此共享程序集引用了客户端不存在的另一个程序集。

我在下面的语句中使用Svcutil.exe注意到错误。在SvcUtil.exe所在的文件夹中打开命令行(对我来说这是C:\ Program Files(x86)\ Microsoft SDKs \ Windows \ v10.0A \ bin \ NETFX 4.6.1 Tools),并在更改以下内容后执行以下语句细分(标记为<>):

SvcUtil.exe /t:code /language:cs  /r:<path of the .dll that contains the types to reuse on client side> <wcf service url>

确保要重复使用的类型的.dll实际上存在于/ bin文件夹中(由于构建错误而可能不存在。)。如果需要,请从服务中复制正确的版本。

SvcUtil将尝试根据来自指定服务的WSDL文档来生成服务和/或数据合同。 / r标记指定.dll在包含可重用类型的客户端上的位置(就像您在使用“添加服务引用”时指定的一样)。

如果重用类型存在问题,则在执行该语句时,它将在命令行中显示。

这可以为您指出共享组件中存在问题的正确方向。

答案 5 :(得分:0)

在这里检查所有答案后,没有任何反应。然后我意识到在浏览器中查看wsdl时我的服务有错误。这应该很明显吧?好吧,看看发生了什么事,我以另一个(无管理员)用户身份打开了服务的解决方案文件,并更新了一种可重用类型的名称。构建了我的解决方案,一切都成功构建。这是我遇到OP描述的问题的时候。

发生了什么事,因为我使用非管理员帐户登录并且没有使用IIS Express。我的WCF项目未加载。这意味着该类型的重命名在WCF项目中没有生效。从而引起问题。

TLDR;在使用方应用程序中查找问题之前,请确保您的服务实际上已启动并正常运行。

答案 6 :(得分:0)

我想我会在答案列表中添加另一种情况:如果您有从公共集合继承的任何类型,例如Dictionary<K, V>,那么当您选择重用类型时,要么需要选择在所有引用的程序集中重用类型,或者,如果选择在指定的引用程序集中重用类型,请确保选择System程序集(通用集合的所在地)除了包含您的数据合同的程序集。

在我们的情况下,我们的类定义遵循以下原则:

public class FooMetadata : Dictionary<Guid, FooMetadataType>
{
}

FooMetadataType[DataContract]的地方。另请注意,您无法用[DataContract]装饰此类,因为Dictionary已被标记为[Serializable];您的服务将编译,但在部署后,浏览到.svc文件时将获得YSOD。