自定义位置的WCF客户端配置

本文关键字:客户端 配置 WCF 位置 自定义 | 更新日期: 2023-09-27 18:19:06

我是WCF的新手,正在尝试制作我的第一个服务(一个简单的使用情况报告服务)。我已经浏览了示例和教程并创建了一个服务。我有一个简单的测试程序,可以运行我的核心代码和发送报告。目前我在调试器中运行本地托管,但运行这个简单的exe程序托管服务,发送报告,服务创建日志文件,就像它应该…一切都好。

现在,我的实际程序是一个插件到另一个商业程序,运行在它的API (Autodesk Revit)。当我在Revit API内部运行完全相同的代码时,我得到一个没有定义端点的错误。我的猜测是,这是因为它正在寻找主Revit.exe.config,显然不会有我的端点定义。我有一个.config文件为我的dll创建(MyLibrary.dll.config),并在执行目录中为我的代码,它正确地定义了端点,但这似乎没有被识别。

所以我的问题是我如何让它从这个配置文件加载连接设置?或者我应该用别的方式来做这件事?我愿意在代码中设置它,只是不知道如何让它连接…

我不确定它是否重要,但这里是在独立程序中工作的配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
      <bindings>
        <basicHttpBinding>
          <binding name="BasicHttpBinding_IReportingService" />
        </basicHttpBinding>
      </bindings>
      <client>
        <endpoint address="http://localhost:8733/Design_Time_Addresses/SPECtrumReportingService/Service1/"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IReportingService"
            contract="ReportService.IReportingService" name="BasicHttpBinding_IReportingService" />
      </client>
    </system.serviceModel>
</configuration>

抛出端点异常的构造函数是:

_reporter = new ReportingServiceClient();

下面是抛出的异常:

Could not find default endpoint element that references contract 'ReportService.IReportingService' 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.
   at System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, 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.ClientBase`1.CreateChannelFactoryRef(EndpointTrait`1 endpointTrait)
   at System.ServiceModel.ClientBase`1.InitializeChannelFactoryRef()
   at RDES.Revit.Sumex.CommonUse.ReportService.ReportingServiceClient..ctor() in c:'RD'Projects'13-004 SPECtrum'Code'SPECtrumBase'Service References'ReportService'Reference.cs:line 241
   at RDES.Revit.Sumex.CommonUse.ImportVM..ctor() in c:'RD'Projects'13-004 SPECtrum'Code'SPECtrumBase'ImportVM.cs:line 41

自定义位置的WCF客户端配置

dll的配置文件与应用程序在同一文件夹中是无关的。只读取应用程序的(可执行的)app.config文件。解决方案是将WCF服务配置从dll配置文件复制到应用程序的app.config文件中。

对于模块化应用程序,另一种解决方案是在代码中设置服务的ABC。这样做的问题是,如果不重新构建和重新部署插件,就无法配置它。

完全在代码中创建WCF代理,您可以使用如下代码:

IServiceContract proxy = ChannelFactory<IServiceContract>.CreateChannel(new WSHttpBinding(),
                    new EndpointAddress("<you url here>"));

我发现了这篇文章,让我找到了一个可能的答案。现在我已经更新了构造函数,如下所示:

_reporter = new ReportingServiceClient(new BasicHttpBinding(), new EndpointAddress("http://localhost:8733/Design_Time_Addresses/SPECtrumReportingService/Service1/"));

我将绑定保留为默认值,尽管看起来我可以根据需要设置其他属性。我只是从独立程序中工作的配置文件中取出端点地址,并使用它来构建。

至少在初步测试中,这似乎是Revit内部预期的工作。有人能评论一下这是否会引起任何问题,或者是否有更好的方法来处理这种情况吗?

虽然您可以通过应用程序代码将端点信息注入代理类ReportingServiceClient,但第一个类编程方法是使用app.config。

在你的客户端配置中,你有一个名为"BasicHttpBinding_IReportingService"的端点,要使用这个端点,你应该这样写:

_reporter = new ReportingServiceClient("BasicHttpBinding_IReportingService");

如果你想

_reporter = new ReportingServiceClient();

要工作,请删除name属性或在客户端配置中定义的客户端端点中使用name属性值。这将是异常提到的所谓的"默认端点元素"。