6

I've been working on creating a self hosted application server in F#. I have the app server up and running and I can connect using a C# client, but some of the things that I want to do are better served using F#. The problem is that I can't seem to get the F# client to work properly. I've found a few examples, but I can't seem to get any of them to work. The most promising is here. Following that example I came up with the following code:

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()

but I get the following error:

Could not find endpoint element with name 'NetTcpBinding_IPrevisionAppServer' and contract 'PrevisionAppServer.Main+IPrevisionAppServer' 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 name could be found in the client element.

I do have an app.config file, and it works just fine in 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>`

For whatever reason, it seems to be ignoring the app.config file. Any ideas? Is there better code to get this working? Any would be appreciated!

UPDATE: Okay, I feel stupid, but I failed to notice that I was running this in a test client that also had a C# UI as the startup, therefore the app.config is in the C# project. So, now the questions becomes, how to I apply the C# app.config to the F# project (I need it this way)? Meaning, I don't really want to code all the getting and setting of properties from the app settings to code. Ideas?

Erick
  • 1,176
  • 15
  • 25
  • 1
    I think that F# doesn't automatically rename the app.config file to [YourExeName].config as C# does, so you might try that. – kvb Jun 01 '11 at 14:51
  • @kvb: Alas, this is not the case; F# executes under `[program files]\fsharp-version\bin\fsi.exe`. You can modify fsi.exe.config and get your config values there, but this is a global file and not easily modified in custom installation scenarios -- might as well modify machine.config :(. See [this question](http://stackoverflow.com/questions/645622/app-config-and-f-interactive-not-working) for more info. – Randolpho Jun 01 '11 at 15:01
  • @Randolpho - you should only need to do that when running the code interactively in FSI. If the application is being compiled, then using a standard configuration file should be fine. For instance, the question you're referring to says "When I run the compiled exe this works great". – kvb Jun 01 '11 at 15:04
  • @kvb -- excellent point. Dunno why I assumed it was running interpreted. Well, I'll let my suggestions remain rather than delete them; perhaps they'll help somebody. – Randolpho Jun 01 '11 at 15:06
  • I'm not running this in the interactive window. This is running compiled code, but regardless, it seems to not see the app.config. I have no problems building it all in code and ignoring the app.config, I just can't find any good examples in F# other than the one I listed. If you know of any good samples, that would great! – Erick Jun 01 '11 at 15:37

2 Answers2

2

Unfortunately, getting F# and App.config to work together is super tricky. See this question for some help on the subject.

Given the hassle configuring F# can be, I suggest you build the whole proxy by hand in code, either setting all of the binding properties manually using in-code literals, or loading and parsing a separate configuration file and setting the binding/behavior properties from values in that file.

I would recommend doing it in a C# assembly with a simple static factory method that your F# code could reference and call to obtain a proxy.

Edit
Well, ignore the above advice, unless you're running in the interpreter. @kvb has the right of that.

That said... looking over your config file... I don't think <endpoint contract="*"> will work; I'm pretty sure you'll have to explicitly specify the contract for client endpoints.

Try this instead:

  <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>
Community
  • 1
  • 1
Randolpho
  • 55,384
  • 17
  • 145
  • 179
  • Randolpho, I did have the correct contract name in there before and got the exact same error. I just forgot to change it back. The main thing is that it seems to ignore the app.config file. – Erick Jun 01 '11 at 15:33
  • @Erick: hmm... Well, one way youcould test the app.config being ignored issue is to add an AppSettings key and testing for it in F# code. Once you've confirmed that app.config is being loaded, you could go back to the proxy issue. The link I provided might help. – Randolpho Jun 01 '11 at 15:56
2

I dunno what the contract="*" thing is (maybe some newer feature of WCF). Anyway the

'PrevisionAppServer.Main+IPrevisionAppServer' 

bit in the diagnostic, where is this type defined? (F# code, C# code, a reference DLL, what?) It looks like a nested type, I wonder if that is affecting things too... I am just fishing.

(The app.config and diagnostics have never been WCF's strongest attribute, sigh.)

Brian
  • 117,631
  • 17
  • 236
  • 300
  • 'PrevisionAppServer.Main+IPrevisionAppServer' is the name of the interface. The naming is a bit odd because it's from F#. 'contract="*"' is a wildcard convention. It didn't change the error. I've been doing some testing and for some reason, F# is not seeing the app.config file. It sees it just fine on my app server, so I'm a bit stumped. – Erick Jun 01 '11 at 19:25
  • I don't understand your 'update' to the question. If you put the app.config in the F# project (that generates an EXE? what kind of project is this?) then it will output yourproject.exe.config next to yourproject.exe and then your config file gets picked up. I'm unclear what your issue or question is now. – Brian Jun 01 '11 at 20:27
  • Brian, I have two projects in the solution, one C# UI which is set as the startup application, and a F# project that I'm trying to use to connect to the server. The app.config that compiled app recognizes is in the C# UI project. The problem is that I can't seem to get the F# project to use that config to instantiate the WCF Service. – Erick Jun 01 '11 at 20:57
  • 1
    You should have an app.config in the F# project too, that has the client's config. If you want to share the same config file, then you can add it as a 'linked' file, see this blog: http://lorgonblog.wordpress.com/2008/08/03/sneak-peeks-into-the-f-project-system-part-three/ – Brian Jun 01 '11 at 22:26
  • Brian, For whatever reason the F# project doesn't see it's own app.config. Thanks for the link! That should work just fine. – Erick Jun 02 '11 at 16:29
  • What is the 'Build Action' in the (right-click, 'properties') properties window for the app.config in the F# project (does it match the C# project?). – Brian Jun 02 '11 at 19:10