【问题标题】:WCF Endpoint Configuration Error: The 'contract' attribute is invalid?WCF 端点配置错误:“合同”属性无效?
【发布时间】:2013-08-16 14:55:09
【问题描述】:

我有一个 WCF 服务,我们称之为UserServiceUserService 引用了一个类库。我们称之为DoWork.dllDoWork.dll 有一个 WCF 服务引用,它指向另一个我们称为 CompanyService 的服务。

现在,当我第一次尝试调用 UserService 时,我会收到一个未配置端点的错误消息。在网上阅读后,我发现我需要将CompanyService 绑定和客户端信息添加到UserServiceweb.config<system.serviceModel> 节点下。

这里是:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IComapnyService" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint name="BasicHttpBinding_ICompanyService"
          address="http://it-dev.company.local:81/Project/Copmpany/CompanyService.svc"
          binding="basicHttpBinding" 
          bindingConfiguration="BasicHttpBinding_IComapnyService"
          contract="CompanyService.ICompanyService"  />
    </client>

我遇到的问题是contract="CompanyService.ICompanyService" 显示错误:

“合同”属性无效 - 根据其数据类型“clientContractType”,值“CompanyService.ICompanyService”无效 - 枚举约束失败。

现在,如果我将 CompanyService 引用直接添加到 UserService WCF 项目,错误就会消失(显然)。但是,我不应该这样做。我已经尝试完全限定 ICompanyService 合同所在的命名空间,但这也不起作用。我已经删除了 .suo 文件并重建了项目,但这也不起作用(在网络上的其他地方建议)。另外,如果我输入contract=,我会得到下拉列表,但找不到CompanyService.ICompanyService(仅当我直接在UserService 项目中引用该服务时)。

我曾尝试使用Tools &gt; WCF Service Configuration Editor 对其进行配置,但这并没有帮助。

我应该注意到一切似乎都工作正常,但我不喜欢智能感知给我蓝色波浪下划线和错误消息的事实。我有一种感觉,我需要在 web.config 中添加其他内容才能使其正常工作,因为 UserService 引用了 DoWork.dll,而 DoWork.dll 又引用了我无法正确查看其合同的 CompanyService

非常感谢任何建议。提前致谢。

【问题讨论】:

  • 我最近遇到了这个问题,发现实际上包含完整的命名空间会导致我的问题。对遇到此问题的其他人有用。

标签: wcf web-config wcf-endpoint


【解决方案1】:

你是对的 - 你不应该这样做。

拥有一个带有“服务引用”(ComanyService) 的 DLL (DoWork.dll) 的架构很糟糕。除非 DLL 已硬编码客户端端点(在代码中)为您调用 CompanyService,否则使用 DLL 的任何人都必须尝试弄清楚如何为他们不知道的服务配置客户端端点。这就是你遇到的。

当您直接从 UserService 添加服务引用时,这样做的原因是,当您这样做时,您会从 CompanyService 元数据中获取 ServiceContract 的副本。为了证明这一点,查看生成的 Reference.cs 文件,搜索 CompanyService,您会发现它具有 [ServiceContract] 属性,将其标识为 WCF 服务。此外,您将看到方法的 [OperationContract] 属性,以及我还可以交换的服务的任何 [DataContracts]。换句话说,所有这些“类型”都被导入到您的项目中,当您编译时,WCF 现在能够在实例化客户端端点时找到这些类型。

如果 CompanyService 是您的服务之一,请考虑将 ServiceContract 定义(接口)提取到单独的 DLL 中。然后,您可以将这些类型作为“程序集引用”从服务 (CompanyService) 和任何客户端应用程序(例如 UserService)中引用。至少这样您就不必添加服务引用。但是,您仍然必须在您的应用程序中填充 .... 部分,以获取您在技术上可能不知道详细信息的服务。不是最好的方法。

更好的方法是将服务依赖项移出 DoWork.dll。您可以通过将逻辑移动到 UserService 实现中来做到这一点。

或者,如果您需要保持 DoWork.dll 独立,则考虑将 DoWork 包装在 WCF 服务上,该服务依赖于 CompanyService。然后,从 UserService 中,添加对新 DoWork 服务的服务引用。这更符合 SOA 的租户,并将允许您的服务独立发展。

【讨论】:

  • 感谢您的信息。也许我的架构很糟糕。 CompanyService 只是一个 WCF 服务,因为我需要它像单例一样使用 InstanceContextMode.Single 的服务行为来运行。现在,在我的系统中,CompanyService 中的一个服务方法绝不应该从 DoWork.DLL 以外的任何地方调用。所以我的后续问题是我应该在 DoWork.DLL 中对端点进行硬编码,还是应该一起取消 ComapnyService 并以某种方式将其逻辑移动到 DoWork.dll 中(以某种方式保持单例行为)?谢谢。
  • 不,不要硬编码端点。我向您展示的最后一个选项可能最适合您的场景。有一些方法(通过安全设置)来确保包装 DoWork.DLL 的服务是唯一可以调用 CompanyService 的服务。所以,像这样的东西。 UserService NewWrapperService (dowork) CompanyService
猜你喜欢
  • 1970-01-01
  • 2012-02-07
  • 2019-03-11
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 2019-04-19
相关资源
最近更新 更多