【问题标题】:How Do I Reference a WCF Client from a WCF Service Without Changing the Latter's Binding?如何在不更改后者绑定的情况下从 WCF 服务引用 WCF 客户端?
【发布时间】:2014-08-23 21:35:15
【问题描述】:

我有一个 C# WCF 服务,我需要引用另一个 Web 服务。旧服务是用 Visual Basic 编写的,不是 WCF。

前者应该弃用后者,但旧服务中有一些方法很复杂。因此,我想从新服务中调用旧服务中的方法。

为了避免命名混乱,我想将旧服务的包装器封装在一个单独的项目中,该项目从新服务中引用。但是,当我尝试从新服务项目调用包装器时,新服务抛出了 InvalidSoapOperation。当我从包装器项目本身调用旧服务时,不会引发此异常。

通常,我会将旧服务的绑定从包装器项目复制并粘贴到新项目中,但由于合同的相似性,我犹豫不决。

有没有办法通过wrapper项目“间接”引用旧服务,使新服务项目不直接耦合旧服务?

编辑:堆栈跟踪如下:

System.InvalidOperationException was unhandled by user code
  HResult=-2146233079
  Message=Could not find default endpoint element that references contract 'OldService.OldServiceSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
  Source=System.ServiceModel
  StackTrace:
       at System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, String configurationName)
       at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName, Configuration configuration)
       at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName)
       at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)
       at System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)
       at System.ServiceModel.ConfigurationEndpointTrait`1.CreateSimplexFactory()
       at System.ServiceModel.ConfigurationEndpointTrait`1.CreateChannelFactory()
       at System.ServiceModel.ClientBase`1.CreateChannelFactoryRef(EndpointTrait`1 endpointTrait)
       at System.ServiceModel.ClientBase`1.InitializeChannelFactoryRef()
       at System.ServiceModel.ClientBase`1..ctor()
       at OldServiceWrapper.OldService.OldServiceClient..ctor() in C:...\MyProject\Service References\TheOldService\Reference.cs:line 21614

Wrapper 项目中的 App.Config:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="OldServiceSoap" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/OldService/OldService.asmx"
                binding="basicHttpBinding" bindingConfiguration="LogOrderSoap"
                contract="OldService.OldServiceSoap" name="OldServiceSoap"/>
        </client>
</system.serviceModel>

【问题讨论】:

  • 异常的内容是什么?这可能只是一个上下文问题,其中运行代码的用户无法访问外部世界。
  • 你能发布一些代码吗?
  • 为包装器和堆栈跟踪发布了工作 app.config。新的 WCF 服务中没有提及旧服务;它所拥有的只是对包装器项目的 Visual Studio“引用”。
  • 如果我可以从我的 Web.Config 中引用客户端的 App.Config 可能会起作用。
  • 我不确定如何访问 App.Config,但我很确定您可以将其内容复制到 Web.Config 中

标签: c# web-services wcf wcf-binding


【解决方案1】:

您构建新服务的方式是旧服务的客户端。因此,您必须将包装器的 app.config 集成到新服务的 web.config 中。

【讨论】:

  • 你会具体做些什么来整合这两者?
  • 合并两个 system.serviceModel 部分。您需要一个包含客户端和服务元素的配置。
  • 我通过从上面的 app.config 文件中复制绑定和客户端元素解决了这个问题。不需要新的服务元素。
  • 这就是我对术语“合并”的意思。对不起,我太不清楚了:-)
【解决方案2】:

解决方法是将引用项目中的绑定和客户端信息复制粘贴到包装器项目中。

C# DLL config file中所述:

虽然很少需要单独跟踪一个用户配置文件中应用的不同副本的设置,但您不太可能希望 DLL 的所有不同用法都相互共享配置。因此,当您使用“正常”方法检索配置对象时,您返回的对象与您正在执行的应用程序域的配置相关联,而不是特定的程序集。

或者正如 Sam Holder 所说的 Reference Web.Config file from another project in same solution C#

类库没有自己的配置。他们使用正在使用的可执行文件的配置。

在 C# 中,标准做法是配置应该属于应用程序,而不是引用的 DLL。因此,将 app.config 信息复制并粘贴到调用项目中是有意义的。这不需要您直接从调用项目中引用旧的 Web 服务,因为我担心它会这样做。

【讨论】:

    猜你喜欢
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多