WCF终结点配置错误:'contract'属性无效?

7
我有一个WCF服务,我们称之为UserServiceUserService引用了一个类库,我们称之为DoWork.dllDoWork.dll又引用了另一个我们称之为CompanyService的WCF服务。
当我首次尝试调用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" 显示错误:

'contract' 属性无效 - 值 'CompanyService.ICompanyService' 根据其数据类型 'clientContractType' 无效 - 枚举约束失败。

如果我直接将 CompanyService 引用添加到 UserService WCF 项目中,错误就会消失(显然)。然而,我不应该这样做。我已经尝试了完全限定 ICompanyService 契约所在的命名空间,但也不起作用。我已经删除了 .suo 文件并重建了项目,但也不起作用(在网上有人建议这样做)。此外,如果我输入 contract=,我可以看到下拉列表,但找不到 CompanyService.ICompanyService(只有当我直接在 UserService 项目中引用服务时才能找到)。
我已经尝试使用 工具 > WCF 服务配置编辑器 进行配置,但没有帮助。
值得注意的是,一切似乎都正常工作,但我不喜欢智能感知给我蓝色波浪线和错误消息的事实。我有一种感觉,我需要在 web.config 中添加其他内容才能使其正常工作,因为 UserService 引用了 DoWork.dll,而 DoWork.dll 又引用了我无法正确查看其契约的 CompanyService
非常感谢您的任何建议。提前致谢。

最近我遇到了这个问题,发现实际上包括完整的命名空间会导致我的问题。对于其他遇到同样问题的人来说,这是一个有用的提示。 - Ian
1个回答

3

你说得对 - 你不应该这样做。

使用具有“服务引用”(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独立,则考虑使用自己的WCF服务包装DoWork,该服务对CompanyService具有依赖性。然后,从UserService中添加对新DoWork服务的服务引用。这更符合SOA的原则,将允许您的服务独立发展。


谢谢提供信息。也许我的架构有问题。CompanyService仅是一个WCF服务,因为我需要它像单例一样运行,并具有InstanceContextMode.Single的服务行为。在我的系统中,CompanyService中的一个服务方法永远不应该从DoWork.DLL以外的任何地方调用。所以我的后续问题是,我应该在DoWork.DLL中硬编码端点,还是完全放弃ComapnyService,并将其逻辑移入DoWork.dll(以某种方式保持单例行为)?谢谢。 - BBauer42
1
不要硬编码端点。我向您提出的最后一个选项可能是适合您场景的最佳选择。有一些方法(通过安全设置)可以确保包装DoWork.DLL的服务是唯一可以调用CompanyService的服务。因此,类似于这样。UserService <--> NewWrapperService (dowork) <--> CompanyService - Rick Rainey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接