WCF常见类型不重用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WCF常见类型不重用相关的知识,希望对你有一定的参考价值。

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

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

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

不知怎的,我已经结束了。还有其他解决方案吗?

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

答案

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

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

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

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

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

这里有一些其他的尝试

  • 打开解决方案的“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模式,因为它不需要“更新服务引用...”,并删除所有生成的代理代码。

另一答案

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

  1. 在我的ServiceContract中注释掉所有未返回原子类型的操作(用OperationContract属性修饰的方法)。
  2. 然后在我的客户端项目中更新我的服务引用。我意识到在我的客户端项目中问题已经解决,我可以输入“[MyServiceReferenceName]”。我的类型没有出现在[MyServiceReferenceName]命名空间中。我通过在XML Schema Browser中打开生成的XSD文件来确认这一点。
  3. 逐个取消注释在步骤1中注释的方法。然后每次更新您的服务引用以查看是否正在重新生成类型。
  4. 一旦找到导致服务引用无法重用类型的方法,请转到每个类,以获取输入或输出到方法的类型。检查您要序列化的所有类是否都使用[DataContract]属性进行修饰。确保使用[DataMember]属性修饰所有字段和属性。此外,确保使用[DataContract]修饰枚举,并使用[EnumMember]修饰每个枚举值。

我希望这可以帮助那些正在经历这个令人沮丧的过程的人,这个问题不一定与共享的dll有关。使用“添加或更新服务参考”时,我的问题并不是真正的问题。问题在于我的实体(模型)类没有用适当的属性进行修饰,以通知DataContractSerializer序列化这些类型。似乎如果序列化的任何部分失败,添加服务引用会添加所有类型。

另一答案

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

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

另一答案

OBJECTCEPTION!

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

建议(解决方案?):确保dll中没有其他对象,或者那些对象上的对象,或者......等与服务中的对象同名的对象。

另一答案

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

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

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

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在客户端上包含可重用类型的位置(就像使用“添加服务引用”时指定的那样)。

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

这可以指出您在共享程序集中出现问题的正确方向。

另一答案

在检查了所有答案后,没有任何效果。然后我意识到我的服务在浏览器中查看wsdl时出错了。这应该是显而易见的吗?好吧,看看发生了什么,我将服务的解决方案文件作为一个不同的(无管理员)用户打开,并更新了其中一个可重用类型的名称。构建我的解决方案并成功构建一切。当我遇到OP描述的问题时。

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

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

以上是关于WCF常见类型不重用的主要内容,如果未能解决你的问题,请参考以下文章

在 GraphQL 中重用输入类型作为片段 [重复]

重用 GraphQL 片段

条件片段和导航重用

视图或片段库为常见数据类型组成 UI

如果我有一个来自Web API 2项目的身份验证过滤器,我可以在WCF服务中重用它吗?

如何从片段到活动而不会干扰片段的可重用性