【问题标题】:How do you create an F# WCF client? I keep getting an app.config error如何创建 F# WCF 客户端?我不断收到 app.config 错误
【发布时间】:2011-09-06 09:10:59
【问题描述】:

我一直致力于在 F# 中创建一个自托管的应用程序服务器。我已经启动并运行了应用服务器,并且可以使用 C# 客户端进行连接,但我想做的一些事情最好使用 F#。问题是我似乎无法让 F# 客户端正常工作。我找到了一些例子,但我似乎无法让它们中的任何一个工作。最有希望的是here。按照那个例子,我想出了以下代码:

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# 项目(我需要这种方式)?意思是,我真的不想将应用程序设置中的所有属性获取和设置都编码为代码。想法?

【问题讨论】:

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

标签: wcf f#


【解决方案1】:

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

'PrevisionAppServer.Main+IPrevisionAppServer' 

诊断中的位,这种类型在哪里定义? (F# 代码、C# 代码、引用 DLL,什么?)它看起来像一个嵌套类型,我想知道这是否也影响了一些事情......我只是在钓鱼。

(app.config 和 diagnostics 从来都不是 WCF 的最强属性,唉。)

【讨论】:

  • 'PrevisionAppServer.Main+IPrevisionAppServer' 是接口的名称。命名有点奇怪,因为它来自 F#。 'contract="*"' 是通配符约定。它没有改变错误。我一直在做一些测试,出于某种原因,F# 没有看到 app.config 文件。它在我的应用服务器上看起来很好,所以我有点难过。
  • 我不明白你对这个问题的“更新”。如果您将 app.config 放入 F# 项目(生成 EXE?这是什么类型的项目?),那么它将在 yourproject.exe 旁边输出 yourproject.exe.config,然后您的配置文件会被拾取。我不清楚您现在的问题或疑问。
  • Brian,我的解决方案中有两个项目,一个是设置为启动应用程序的 C# UI,另一个是我试图用来连接服务器的 F# 项目。编译后的应用程序识别的 app.config 位于 C# UI 项目中。问题是我似乎无法让 F# 项目使用该配置来实例化 WCF 服务。
  • F# 项目中也应该有一个 app.config,其中包含客户端的配置。如果您想共享相同的配置文件,则可以将其添加为“链接”文件,请参阅此博客:lorgonblog.wordpress.com/2008/08/03/…
  • Brian,无论出于何种原因,F# 项目都看不到它自己的 app.config。感谢您的链接!这应该可以正常工作。
【解决方案2】:

不幸的是,让 F# 和 App.config 一起工作非常棘手。有关该主题的一些帮助,请参阅this question

考虑到配置 F# 可能会很麻烦,我建议您在代码中手动构建整个代理,或者使用代码内文字手动设置所有绑定属性,或者加载和解析单独的配置文件并设置绑定/该文件中值的行为属性。

我建议在 C# 程序集中使用简单的静态工厂方法执行此操作,您的 F# 代码可以引用并调用该方法以获取代理。

编辑
好吧,忽略上面的建议,除非你在解释器中运行。 @kvb 有权这样做。

也就是说...查看您的配置文件...我认为&lt;endpoint contract="*"&gt; 不会起作用;我很确定您必须明确指定客户端端点的合同。

试试这个:

  <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:嗯...嗯,您可以测试 app.config 被忽略问题的一种方法是添加 AppSettings 键并在 F# 代码中对其进行测试。确认 app.config 正在加载后,您可以返回代理问题。我提供的链接可能会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
相关资源
最近更新 更多