There are no such templates as of yet, but if you're looking for sample WCF code in F#, there's a little in one of my blogs: [link:lorgonblog.spaces.live.com]

Offhand, the only WCF shortcoming I can think of with respect to F# is that you can't use svcutil.exe (or 'Add Service Reference') to generate F# client code from server metadata (WSDL). But most everything else for WCF should translate over to F# pretty directly, I think. Let me know if you have further specific questions.

By on 8/29/2008 7:41 PM ()

Thanks Brian.

My work so far has (inter alia) involved going beyond the templates in the conventional languages (and adding updated intellisense support to the JavaScript language extension that I'm using...).

Such things are not well documented, but are fairly easily doable, like declaring a WebScriptServiceHostFactory, to avoid tedious web.config configuration. (If anybody else is doing this the BodyStyle of a WebInvoke declaration, might need to be something other than "Wrapped". Some surprisingly good diagnostic information gets written to the event log!)

I'll be sending larger, more complex data structures, as Json, to the web methods and returning complex data to the browser. So I'm currently on a bit of a detour getting the information over the wire.

Your example has simpler data than that, going over the wire.

I suspect that the idea of funnelling a web service via a conventional language WCF service to F# might be the way to go, (though that could present challenges of it's own ...) at least until I see that somebody else has exercised challenging designs in a production setting.

By on 8/30/2008 4:56 PM ()

sorry to wake up an old and buried thread, but i stumbled on this through google.

we've gotten an alternative version to work. we built out the fsharpextensions library for bistro to let you write controllers in f#, directly. you combine that with a no-template return, returning xml or json (or any other data) instead, and you have a RESTful web service written in f#.

we're using the c# version of bistro for production web service work, but there's no reason why the f# extension wouldn't work equally well.

full disclosure - i'm one of the guys working on bistro.

By on 5/25/2009 7:52 PM ()

In a sense, you're certainly on safer footing with a conventional language implementation of your WCF service. But just for fun I put together a slightly more complex one, and everything appears to work smoothly, so if you're feeling adventurous, you can do more pioneering in this space.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#light

open System 
open System.IO
open System.Net
open System.ServiceModel 
open System.ServiceModel.Web
open System.Runtime.Serialization 

[<DataContract>]
type Person() =
    let mutable name = ""
    let mutable age = 0
    [<DataMember>]
    member public x.Name with get() = name
                         and set(s) = name <- s
    [<DataMember>]
    member public x.Age with get() = age
                        and set(x) = age <- x

[<ServiceContract>] 
type IMyContract = interface 
    [<OperationContract>] 
    [<WebGet(BodyStyle = WebMessageBodyStyle.Wrapped,
                RequestFormat = WebMessageFormat.Xml,
                ResponseFormat = WebMessageFormat.Xml,
                UriTemplate = "Get")>]
    abstract Get: unit -> Person 
    [<OperationContract>] 
    [<WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedResponse,
                RequestFormat = WebMessageFormat.Xml,
                ResponseFormat = WebMessageFormat.Xml,
                UriTemplate = "Foo")>]
    abstract Older: p:Person -> Person 
end 


type MyService() = class 
    interface IMyContract with 
        member this.Older (p:Person) =
            let r = new Person()
            r.Name <- p.Name
            r.Age <- p.Age + 1
            r
        member this.Get() =
            new Person(Name="John", Age=40)
end 

let DoWCFRun () = 
    let addr = "http://localhost/WCF" 
    let address = new Uri(addr) 
    let host = new WebServiceHost(typeof<MyService>, [|address|]) 
    let binding = new WebHttpBinding() 
    host.AddServiceEndpoint(typeof<IMyContract>, binding, "") |> ignore 
    host.Open() 

    let webReq = WebRequest.Create("http://localhost/WCF/Foo")
    webReq.Method <- "POST"
    webReq.ContentType <- "application/xml"
    let brian = new Person(Name = "Brian", Age = 32)
    let reqStream = webReq.GetRequestStream()
    let ser = new DataContractSerializer(typeof)
    ser.WriteObject(reqStream, brian)
    reqStream.Close()
    printfn "sending request..."
    use webResp = webReq.GetResponse() :?> HttpWebResponse
    printfn "%s" webResp.StatusDescription
    use respStream = webResp.GetResponseStream()
    use respReader = new StreamReader(respStream)
    printfn "%s" (respReader.ReadToEnd())
    
    host.Close() 


DoWCFRun()

printfn "press a key" 
Console.ReadKey() |> ignore
By on 8/31/2008 5:46 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper