【问题标题】:WCF Fails to generate client proxyWCF 无法生成客户端代理
【发布时间】:2010-12-10 22:51:04
【问题描述】:

我有一个奇怪的问题,我似乎无法诊断,这似乎是 PEBCAC 的问题,但我花了很多时间试图解决它。我创建了一个通过 Windows 服务托管的 WCF 服务。这项服务已经运行了一段时间,我有一个 Windows 窗体和一个 Web 界面。该服务最初是在 XP 上开发的,但我最近迁移到了 Windows 7。当我迁移时,我发现该服务的 Windows 安全性阻止我在 Windows 7 上使用我的 WinForms 应用程序,但它在 XP 上运行良好Windows Server 2008 R2、Windows 7 和 XP 上的服务。为了简化开发过程中的事情,我完全禁用了安全性,并且我的 WinForms 应用程序在 windows7 上再次运行。

然后我对 WCF 服务进行了一些其他更改,添加方法、更改数据协定等。唯一的端点更改是禁用 wshttp 的安全性。突然,更新 Web 应用程序的服务引用不再创建客户端代理,但它确实生成了 wsdl 和 xsd 文件。我在 XP 和 Win7 上尝试了许多新旧服务的组合,结果是:

  1. 旧服务在更新引用时运行良好,无论是在 XP 还是 Win7 上运行,也无论 Web 应用代码是在 XP 还是 Win7 上。
  2. 新服务不会创建代理,无论是在 XP 还是 Win7 上运行,也无论 Web 应用程序代码是在 XP 还是 Win7 上。我没有从服务参考更新中得到任何错误,但是,configuration.svcinfoconfiguration91.svcinfo 文件没有列出任何行为、绑定或端点。其余文件看起来都很好。
  3. 我可以使用svcutil 获取元数据并使用新版本的服务生成代理代码。
  4. 更新服务引用时,我确实在对象资源管理器中显示了属于数据协定一部分的两项,但只有一项是正确的。我没有得到客户端或其他数据合同对象。
  5. 关键在于 Windows 窗体应用程序与新服务配合得很好,包括更新引用和调用服务方法。嗯?

我查看了新服务中的服务、行为和端点定义,它们与旧服务相匹配。网上没有我能找到这样一个错误的参考。我意识到我必须在新代码中做错了什么,但由于它在 WinForms 应用程序中运行良好,我无法解释其中的差异。

任何帮助将不胜感激。也许我可以保留一些头发;)

-编辑-

在阅读了答案后,我做了更多的研究并尝试了更多的东西:

我已经查看了没有安全性的服务的 xsd 等文件,并且在将事物恢复到具有 DataContract 属性的顶级枚举的方式之后(没有这些),并且还恢复了安全值恢复到以前的水平。在这两种情况下,我都没有发现任何问题,只是文件的名称不同:旧的服务引用使用 xsd 文件,其数字后缀范围为 2 - 5,而最新的服务引用使用 1 - 4(看不出这应该影响事物,因为 svcmap 中的指针似乎是正确的)。它确实使区分事物变得更加困难,但我已经详细查看了每个文件,数据似乎正确,只是放在不同的文件中。

wsdl 文件,在安全性恢复到旧值后,除了主机 IP 和机器名称外,与预期相同。但是configuration.svcinfoconfiguration91.svcinfo 仍然没有定义端点、行为或绑定。此外,奇怪的是,在确实定义的两个数据合约中,一个只有一个新成员:它的数据成员不存在。这是一个引用标记为Serializable 的类的数据协定,但未使用DataContract 属性列出。唯一改变的是我在类中添加了一个新的字符串成员。更奇怪的是,在 xsd 文件中数据协定类的定义是正确的。

我很困惑。

【问题讨论】:

    标签: visual-studio-2008 wcf


    【解决方案1】:

    是的,您的应用程序可能引用了您的合同程序集,当您通过“添加服务引用...”生成代理时,您正在重用引用程序集中的类型,这就是您的合同实体没有被引用的原因生成。 为了解决这个问题,当您添加服务引用时,我建议您单击“高级”按钮,然后您应该取消选中“在引用的程序集中重用类型”选项,或者只是从您的应用程序中删除合同程序集引用。

    我希望这对你有用!

    【讨论】:

      【解决方案2】:

      好吧,经过一番折腾,我终于想通了。问题是由于我在 Web 应用程序中使用与服务中使用的程序集相同的程序集(我在 Web 应用程序中使用了程序集的不同部分)。这导致作为数据合同一部分的类以及我为服务的使用而修改的类在 Web 应用程序的编译程序集中与正在发布的服务不同。这反过来又导致服务引用无法生成客户端代理。如果没有客户端代理,我的 Web 应用程序代码会显示错误,因此我从未尝试编译解决方案。简单的答案是仅在 Web 应用程序中构建公共程序集(有效),然后服务引用正确生成代理。想象一下,让一个类的单个数据成员成为问题的明显原因,但它的名称、数据类型、在代码中的位置等对问题没有影响,我是多么困惑!无论如何,无论如何重用这个程序集可能是糟糕的设计 - 可能更好地从服务本身使用这些信息。最后一点,winform 应用程序工作的原因是因为我也在 winform 应用程序中使用相同的程序集,并且在我编译应用程序时它始终保持最新,因此更改从不冲突。希望这对将来的某人有所帮助。作为对 Microsoft 的附注 - 有关此冲突的任何错误信息都会极大地帮助解决故障,尽管我承认这可能不是常见的情况。

      【讨论】:

        【解决方案3】:

        这是一个很长的镜头,但是当您比较生成的 xsd 时会发生什么?这些差异是您所期望的,还是其中有一些没有意义的奇怪变化?我问是因为我们发现在操作的顶层涉及枚举的某些合约更改会导致 wsdl.exe 的行为不同。它似乎回退到使用 XmlSerializer 而不是 DataContractSerializer,这有很多副作用,例如类型从列表更改为数组。不过,我不记得客户端代码生成是否也存在问题。

        【讨论】:

        • 有趣的是,我碰巧在顶层添加了一个枚举作为更改的一部分。我会比较 xsds 并看看那里有什么。谢谢 - 我永远不会想到这样的问题。您是如何解决问题的?
        • 我们(偶然)发现了一些变通方法。不太令人满意的是通过将枚举包裹在其他结构中来将枚举向下移动。更好的解决方法是确保 MessageBodyMemberAttribute 的 Name 属性与枚举的类型相同。
        猜你喜欢
        • 2012-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-11
        • 2010-10-22
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        相关资源
        最近更新 更多