Monday, January 26, 2009

F# and WCF: Data Contracts

F# offers the WCF developer a number of options for defining data contracts. You can use standard classes, constructed classes, or record types to define your data contracts. The key thing to remember is that the DataContractSerializer requires writeable properties. Let's take a look at a simple data contract defined in each of the three ways mentioned.

Standard Types

[<DataContract>]
type MyDataContract =
val mutable x : string

new() = { x = "" }

[<DataMember>]
member this.MyDataMember
with get() = this.x
and set v = this.x <- v


Constructed Types

[<DataContract>]
type MyDataContract() =
let mutable x = ""

[<DataMember>]
member this.MyDataMember
with get() = x
and set v = x <- v


Record Types

[<DataContract>]
type MyDataContract =
{ [<DataMember>] mutable MyDataMember : string }


Of the three, I prefer to use record types to define my data contracts. A record type mirrors the intention behind defining a data contract where we are simply declaring a set of data fields by name and type. If you've used the XmlSerializer much, you are probably aware of the default constructor requirement. This restricted the use of record types since they do not get a default constructor. Thankfully, that restriction does not apply with the DataContractSerializer. In addition, you can remove the DataContract and DataMember attributes from your type definition if you are using .NET 3.5 Service Pack 1 although I wouldn't recommend that you do this on a routine basis.

You should use the DataContract attribute to control the namespace and name of your contract. Thus, a good data contract in F# would look something like this:
[<DataContract(
Namespace = "http://schemas.vernagus.blogspot.com/01/2009",
Name = "MyDataContract")>]
type MyDataContract =
{ [<DataMember>] mutable MyDataMember : string }


When we create an instance of our contract and serialize it, we get the following:
<MyDataContract xmlns="http://schemas.vernagus.blogspot.com/01/2009"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<MyDataMember>my value</MyDataMember>
</MyDataContract>


In my next post I will explore more advanced data contract concepts like collections and enumerations.

1 comment:

fengfk2008 said...
This comment has been removed by a blog administrator.