如何创建一个F# WCF客户端?我不断收到app.config错误。

6

我一直在尝试使用F#创建自托管应用程序服务器。我已经成功启动了应用程序服务器,并且可以使用C#客户端进行连接,但是我想要做的一些事情更适合使用F#。问题是我似乎无法使F#客户端正常工作。我找到了一些例子,但是似乎没有一个能够正常运行。最有希望的是这里。根据该示例,我编写了以下代码:

let address= new EndpointAddress("net.tcp://192.168.101.100:2009/PrevisionService/tcp")
let factory = new ChannelFactory<IPrevisionAppServer>("NetTcpBinding_IPrevisionAppServer", address)
let channel = factory.CreateChannel()//address)
let GetDataObject (sql) = channel.GetDataObject(sql)
factory.Close()

但我遇到了以下错误:

在ServiceModel客户端配置部分未找到名称为'NetTcpBinding_IPrevisionAppServer'、合同为'PrevisionAppServer.Main+IPrevisionAppServer'的终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为在客户端元素中找不到与此名称匹配的终结点元素。

我有一个app.config文件,在C#中它也很好用:

<?xml version="1.0" encoding="utf-8"?>
<!--Client Config-->
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_IPrevisionAppServer" closeTimeout="00:01:00"
          openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
          hostNameComparisonMode="StrongWildcard"
          maxBufferSize="2147483647"
          maxBufferPoolSize="2147483647"
          maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647"
            maxStringContentLength="2147483647"
            maxArrayLength="2147483647"
            maxBytesPerRead="2147483647"
            maxNameTableCharCount="2147483647" />
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://192.168.101.100:2009/PrevisionService/tcp" behaviorConfiguration="ServiceViewEventBehavior"
          binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPrevisionAppServer"
          contract="*" name="NetTcpBinding_IPrevisionAppServer">
      </endpoint>
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ServiceViewEventBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>`

出于某种原因,它似乎忽略了app.config文件。有什么想法吗?有更好的代码可以让它工作吗?任何建议都将不胜感激!
更新:好吧,我感觉很蠢,但我没有注意到我在一个测试客户端中运行这个程序,该客户端也有一个C# UI作为启动项,因此app.config位于C#项目中。所以,现在的问题是,如何将C# app.config应用于F#项目(我需要这样做)?也就是说,我真的不想编写所有从应用程序设置到代码的属性获取和设置的代码。有什么想法?

1
我认为F#不像C#那样自动将app.config文件重命名为[YourExeName].config,所以你可以尝试一下。 - kvb
@kvb:唉,情况并非如此;F#在[program files]\fsharp-version\bin\fsi.exe下执行。您可以修改fsi.exe.config并在其中获取配置值,但这是一个全局文件,在自定义安装方案中不容易修改 - 最好修改machine.config :(. 有关更多信息,请参见此问题 - Randolpho
@Randolpho - 只有在使用 FSI 交互式运行代码时才需要这样做。如果正在编译应用程序,则使用标准配置文件即可。例如,你所提到的问题说“当我运行编译后的 exe 文件时,这个方法非常好用”。 - kvb
@kvb -- 非常好的观点。不知道为什么我认为它是运行解释的。嗯,我会让我的建议保留而不是删除它们;也许它们会帮助某个人。 - Randolpho
我没有在交互式窗口中运行这个程序。这是运行已编译的代码,但无论如何,它似乎无法看到app.config文件。我没有问题在代码中构建所有内容并忽略app.config,我只是找不到任何好的F#示例,除了我列出的那个之外。如果您知道任何好的示例,那就太好了! - Erick
2个回答

2
很遗憾,让F#和App.config配合起来使用非常棘手。关于此问题,请参考这个问题以获得一些帮助。
鉴于配置F#的麻烦,我建议您通过代码手动构建整个代理,可以使用内部代码文字手动设置所有绑定属性,也可以加载和解析单独的配置文件,并从该文件中的值设置绑定/操作属性。
我建议您在C#程序集中完成,使用一个简单的静态工厂方法,您的F#代码可以引用并调用以获取代理。 编辑
好吧,忽略上面的建议,除非你在解释器中运行。@kvb是正确的。
话虽如此...查看您的配置文件...我认为<endpoint contract="*">不会起作用;我相当确定您必须明确指定客户端端点的协定。
请改用以下内容:
  <endpoint address="net.tcp://192.168.101.100:2009/PrevisionService/tcp" behaviorConfiguration="ServiceViewEventBehavior"
      binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPrevisionAppServer"
      contract="Correct.Namespace.IPrevisionAppServer" name="NetTcpBinding_IPrevisionAppServer">
  </endpoint>

Randolpho,我之前确实在那里有正确的合同名称,但是得到了完全相同的错误。我只是忘记改回来了。主要问题是它似乎忽略了app.config文件。 - Erick
@Erick:嗯...好吧,你可以测试app.config被忽略的问题的一种方法是添加一个AppSettings密钥并在F#代码中进行测试。一旦确认加载了app.config,你就可以回到代理问题上。我提供的链接可能会有所帮助。 - Randolpho

2

我不知道contract="*"是什么(可能是WCF的一些新功能)。无论如何,

'PrevisionAppServer.Main+IPrevisionAppServer' 

在诊断中的“bit”,这种类型是在哪里定义的?(F#代码,C#代码,引用DLL,还是其他什么?)看起来像是一个嵌套类型,我想知道它是否会影响到问题...我只是试探一下。

(app.config和诊断从来都不是WCF的强项,叹气。)


'PrevisionAppServer.Main+IPrevisionAppServer'是接口的名称。命名有点奇怪,因为它来自F#。'contract="*"'是通配符约定。它没有改变错误。我一直在进行一些测试,但由于某种原因,F#无法看到app.config文件。它在我的应用服务器上看起来很好,所以我有点困惑。 - Erick
我不理解你对问题所做的“更新”。如果你将app.config放在生成EXE文件的F#项目中(这是什么类型的项目?),那么它将在yourproject.exe旁边输出yourproject.exe.config,然后你的配置文件就会被捡起来。我现在不清楚你的问题或疑问是什么。 - Brian
Brian,我在解决方案中有两个项目,一个是设置为启动应用程序的C# UI,另一个是我正在尝试使用它连接到服务器的F#项目。编译后的应用程序识别的app.config位于C# UI项目中。问题是我似乎无法让F#项目使用该配置来实例化WCF服务。 - Erick
1
你在 F# 项目中也应该有一个 app.config,其中包含客户端的配置。如果你想共享同一个配置文件,那么你可以将其添加为“链接”文件,参见这篇博客:http://lorgonblog.wordpress.com/2008/08/03/sneak-peeks-into-the-f-project-system-part-three/。 - Brian
Brian,由于某种原因,F#项目无法看到自己的app.config。感谢提供的链接!那应该可以正常工作。 - Erick
在 F# 项目中,(右键单击,“属性”) 属性窗口中的 app.config 中,“Build Action” 是什么意思(是否与 C# 项目匹配)? - Brian

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