WCF常见类型未重用

发布于 2024-12-18 09:25:35 字数 547 浏览 5 评论 0原文

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

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

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

我不知何故不知所措。还有其他解决方案吗?

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

Hint: This questions has many duplicates, but none of the solutions works for me.

What I have is a web service and a client, both having references to a shared assembly "DataModel". I'm creating the service proxy using the "Add service reference..." dialog and select "Reuse types in all referenced assemblies", but still it creates new types instead of reusing mine.

  • It used to work, but now suddenly it's not reusing types anymore
  • Referencing the shared assembly before adding the service reference does not work
  • Restarting VS2010 does not help (I have all updates)
  • I tried with a simple POCO class (just a simple class containing an integer property), also no luck
  • Deleting and re-adding the service reference (or the shared assembly reference) did not help
  • Only selecting the shared assembly in "Reuse types in specified referenced assemblies" - no luck
  • svcutil.exe /reference yields the same result

I'm at wit's end somehow. Are there any other solutions?

EDIT: I should add that I just reset my project to earlier commits, and whichever commit I use, still the same problem. And I know it worked with earlier commits!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

饮惑 2024-12-25 09:25:35

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

您需要执行此操作,或者至少在添加引用后更新服务引用。

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

,您不需要这样做,但我也会尝试一下。

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

这里还有一些其他可以尝试的事情

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

如果所有其他方法都失败,则强制两侧使用相同对象的最佳方法是完全删除“服务引用”代理并使用 ChannelFactory 方法。请参阅更简单的说明如何调用 WCF 服务而不添加服务引用VS2010 添加服务引用相对于直接 ClientBase 的优势 。这是我首选的 WCF 模式,因为它消除了“更新服务引用...”的需要,并删除了所有生成的代理代码。

Referencing the shared assembly before adding the service reference does not work

You would need to do this, or at least update the service reference after adding the reference.

Deleting and re-adding the service reference (or the shared assembly reference) did not help

and you shouldn't need to do this, but I would've tried it too.

In order for the 'reuse' to work both projects (client and service) need to be using the same version of the assembly. You're referencing the project, which is good - I've encountered this before when referencing the assembly directly because of different versions.

Here's some other things to try

  • Open 'Configuration Manager' for your solution - make sure that the shared assembly is configured to build.
  • Ensure you're using a project reference for both client and service - using the latest assembly on the client won't help if the service is using an older version.
  • Delete the project reference and build, and expect the build to fail - if it doesn't fail then you must be referencing something else.
  • Manually check that the latest 'shared assembly' is being included in the build in both service and client - check the bin folder, check the assembly version / build date.

If all else fails, the best way to force the same object on both sides is to remove the 'service reference' proxy altogether and use the ChannelFactory method. See Simpler Explanation of How to Make Call WCF Service without Adding Service Ref and VS2010 Advantages of Add Service Reference over direct ClientBase<>. This is my preferred WCF pattern because it removes the need to 'Update service reference...', and removes all that generated proxy code.

翻了热茶 2024-12-25 09:25:35

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

  1. 注释掉所有操作(用OperationContract属性修饰的方法)在我的ServiceContract中不返回原子类型
  2. 然后在我的客户项目中更新我的服务参考。当我在我的客户端项目中输入“[MyServiceReferenceName]”时,我意识到问题已经解决。我的类型没有出现在 [MyServiceReferenceName] 命名空间中。为了确定这一点,我通过在 XML 模式浏览​​器中打开生成的 XSD 文件来验证这一点。
  3. 逐一取消注释第 1 步中注释的方法。然后每次更新您的服务引用以查看类型是否被恢复
  4. 一旦您找到导致服务引用无法重用类型的方法,请转到每个类以查找作为该方法的输入或输出的类型。检查您希望序列化的所有是否都用 [DataContract] 属性修饰。确保所有字段属性都用[DataMember] 属性修饰。另外,请确保枚举用 [DataContract] 修饰,并且每个枚举值都用 [EnumMember] 修饰。

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

I just went through an entire day trying to find out why the Types in my shared dll were not being reused when I added a Service Reference in VS2013. It turns out that the service had several problems related to serialization. I had a couple of enumerations that did not have the EnumMember attribute. The way I solved my issues were by trying the following steps:

  1. Commenting out all operations (methods decorated with OperationContract attribute) in my ServiceContract that did not return atomic Types.
  2. Then updating my Service Reference in my client project. I realized that the problem had been resolved when in my client project, I was able type "[MyServiceReferenceName]." and my Types did not appear in the [MyServiceReferenceName] namespace. I verified this by opening the generated XSD files in the XML Schema Browser just to be certain.
  3. One by one, uncomment a method that was commented in Step 1. Then update your Service Reference each time to see if the types are or are not being resued.
  4. Once you find the method that is causing the Service Reference to fail to reuse Types, go to each class for the the Types that are either input or output to the method. Check that all classes that you wish to serialize are decorated with the [DataContract] attribute. Ensure that all fields and properties are decorated with the [DataMember] attribute. Also, ensure enums are decorated with [DataContract] and that each enumeration value is decorated with [EnumMember].

I hope this helps others who are going through this frustrating process and this problem is not necessarily related to a shared dll. My issue was not really an issue with using Add or Update Service Reference. The problem lied with my entity (model) classes not being decorated with the proper attributes to notify the DataContractSerializer to serialize those types. It seems that if any part of serialization fails, adding the Service Reference adds all the Types.

海风掠过北极光 2024-12-25 09:25:35

这个可能性有点大,但一种可能性是旧版本的共享 dll 位于 GAC 中。

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

It is a bit of a long shot, but one possibility is that an old version of the shared dll is in the GAC.

It tries to use the shared dll, finds a dll with types missing, and then reverts to creating types.

空心↖ 2024-12-25 09:25:35

反对!

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

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

OBJECTCEPTION!

We recently had the same problem where I work. It took us four hours to hunt down the problem, but we eventually discovered that an enum on an object within the same dll as the object it was refusing to copy had the same name as another enum that was being used in the service, so it refused to reuse any types from that dll.

Suggestion(solution?):
Make sure that there are no other objects in the dlls, or objects on those object, or... etc.
that have the same name as one in your service.

妖妓 2024-12-25 09:25:35

这是一个老话题,但由于我今天遇到了同样的问题,我想分享我的解决方案。

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

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

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

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

This is an old topic, but since I ran into the same problem today I want to share my fix.

For me the problem was that the shared assembly was correctly added in both projects (service and client), but on service side this shared assembly referenced another assembly that was not present on client side.

I noticed the error using Svcutil.exe with below statement. Open the commandline in the folder where SvcUtil.exe is located (for me this is C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools) and execute below statement after changing below segments (marked with <>):

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

make sure that the .dll of the types you want to reuse physically exist in the /bin folder (maybe not there due to build error,...). If needed copy a correct build from the service.

SvcUtil will try to generate service and/or data contracts based on the WSDL document from the specified service. The /r tag specifies where the .dll is located on the client side that contains the reusable types (just like you specify when using "Add service reference").

if there is a problem with reusing types it will be displayed in the command line when the statement is executed.

This can point you in the right direction where the problem lies in your shared assembly.

药祭#氼 2024-12-25 09:25:35

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

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

太长了;在使用应用程序中查找问题之前,请确保您的服务确实启动并正常工作。

After checking all the answers here, nothing worked. Then I realized that my service had an error when viewing the wsdl in the browser. This should be obvious right? Well, see what happened is I opened the service's solution file as a different(none admin) user and updated the name of one of the reusable types. Built my solution and everything built successfully. Which is when I ran into the issue described by the OP.

What happened was, because I logged in with a non-admin account and I wasn't using IIS express. My WCF project did not load. Meaning that the rename of the type did not take effect in the WCF project. Thus causing the issue.

TLDR; make sure your service actually starts and works correctly, before looking for issue in the consuming application.

假装爱人 2024-12-25 09:25:35

我想我应该在答案列表中添加另一种情况:如果您有任何从公共集合继承的类型,例如 Dictionary,当您选择重用类型时,您要么需要选择在所有引用的程序集中重用类型,或者,如果您选择在指定的引用程序集中重用类型,请确保选择系统另外,程序集(通用集合的所在地)到包含数据协定的程序集。

在我们的情况下,我们的类定义如下:

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

其中 FooMetadataType[DataContract]。另请注意,您不能使用 [DataContract] 修饰此类,因为 Dictionary 已标记为 [Serializable];您的服务将编译,但在部署时,您将在浏览到 .svc 文件时收到 YSOD。

I thought I would add another situation to the list of answers: if you have any types that inherit from a common collection, like Dictionary<K, V>, when you choose to reuse types, you either need to choose to Reuse types in all referenced assemblies, or, if you choose to Reuse types in specified referenced assemblies, make sure you choose the System assembly (home to the generic collections) in addition to the assembly that contains your data contracts.

In our situation our class definition was along the lines of:

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

Where FooMetadataType was a [DataContract]. Also note that you cannot decorate this class with [DataContract] because Dictionary is already marked as [Serializable]; your service will compile but upon deployment you will get a YSOD when browsing to the .svc file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文