0

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

现在,我的实际程序是另一个在其 API (Autodesk Revit) 中运行的商业程序的插件。当我在 Revit API 中运行完全相同的代码时,我收到一个错误,即没有定义端点。我的猜测是这是因为它正在寻找主要的 Revit.exe.config 显然不会定义我的端点。我为我的 dll 创建了一个 .config 文件(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

任何帮助将不胜感激...

4

3 回答 3

2

it's not relevant that the dll's configuration file is in the same folder as the application. only the application's (executable's) app.config file is read. the solution is to copy the WCF service configuration from the dll config file to you application's app.config file.

the other solution, for modular applications, is to set the service's ABC in code. the problem with this is that you cannot configure it without rebuilding and redeploying the addin.

to create a WCF proxy entirely in code you could use something like this:

IServiceContract proxy = ChannelFactory<IServiceContract>.CreateChannel(new WSHttpBinding(),
                    new EndpointAddress("<you url here>"));
于 2014-08-22T05:43:16.663 回答
0

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

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

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

至少在初步测试中,这似乎在 Revit 内部按预期工作。任何人都可以评论这是否会导致任何问题,或者是否有更好的方法来处理这种情况?

于 2014-08-22T05:35:44.193 回答
0

Though you can inject endpoint info into a proxy class ReportingServiceClient through your application codes, the first class programming approach is to use app.config.

In your client config, you have an endpoint named "BasicHttpBinding_IReportingService", to use this endpoint, you should then write:

_reporter = new ReportingServiceClient("BasicHttpBinding_IReportingService");

If you want

_reporter = new ReportingServiceClient();

to work, remove the name attribute or make the name attribute value in the client endpoint defined in the client config. This will be the so called "default endpoint element" mentioned by the exception.

于 2014-08-22T06:37:41.663 回答