Geeks With Blogs
A Software Engineering Blog by Nick Holmes

[Update: This blog post was orignally posted in early 2008, in another blog. Things have changed a little in F#, and Ted Nedward has provided updated information related to this, showing how to create data contracts in F#]

On the road to a really interesting Web Service, I increased the complexity of my "could-not-be-simpler" web service one notch, and added a class-typed argument to the operation. This requires constructing of a Data Contract, so that WCF can build the correct WSDL, and also know how to serialize (and de-serialize) messages. As with the Service Contract, this is simply done with a couple of attributes, like this:

[<DataContract>]
type public SimpleDataContract() =
        let mutable _propertyOne = System.String.Empty
        let mutable _propetyTwo = 0
        [<DataMember>]
        member public x.PropertyOne
            with get() = _propertyOne
            and set(value) = _propertyOne <- value           
        [<DataMember>]
        member public x.PropertyTwo
            with get() = _propetyTwo
            and set(value) = _propetyTwo <- value

[<ServiceContract(ConfigurationName = "ISimpleService", Namespace = "http://coyote-software.com/FSWCF/SimpleService")>]
type ISimpleService =
    [<OperationContract>]
    abstract TestMethod: Param:SimpleDataContract -> string

[<ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)>]
type SimpleService() =
    interface ISimpleService with
        member x.TestMethod s = "Hello " + s.PropertyOne;

Unfortunately, code causes a run-time exception when the service is started (well before any messages arrive). The error is about "method get_PropertyOne" not being a property, and therefore an invalid recipient of the DataMember attribute. I strongly suspect that this is due to a know bug in the current F# compiler emitting IL for properties in a non-standard way.

(WCF data contract members must be placed on properties, and not fields.)

The obvious work-around is to create the class in C#. The equivalent C# class is simply:

    [DataContract]
    public class SimpleDataContract
    {
        public SimpleDataContract() { }

        [DataMember]
        public string PropertyOne { get; set; }
        [DataMember]
        public int PropertyTwo { get; set; }
    }

  

For once, C# trumps F# for brevity! Anyway, using this class from F# is no more complex than referencing the dll, and removing the F# SimpleDataContract class, and the web service now works as expected.

The next step is to do something a little more interesting in the operation; use LINQ to SQL to query a database, and return some data. As it turns out, our data contracts will be again come via C#, so this issue will be by-passed.

Posted on Wednesday, May 6, 2009 3:09 PM F# , Functional Programming | Back to top


Comments on this post: Problems with WCF Data Contracts in F#

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Nick Holmes | Powered by: GeeksWithBlogs.net