views:

2132

answers:

1
+7  Q: 

WCF DataContracts

I have a WCF service hosted for internal clients - we have control of all the clients. We will therefore be using a data contracts library to negate the need for proxy generation. I would like to use some readonly properties and have some datacontracts without default constructors. Thanks for your help...

+11  A: 

Readonly properties are fine as long as you mark the (non-readonly) field as the [DataMember], not the property. Unlike XmlSerializer, IIRC DataContractSerializer doesn't use the default ctor - it uses a separate reflection mechanism to create uninitialized instances. Except on mono's "Olive" (WCF port), where it does use the default ctor (at the moment, or at some point in the recent past).

Example:

using System;
using System.IO;
using System.Runtime.Serialization;
[DataContract]
class Foo
{
    [DataMember(Name="Bar")]
    private string bar;

    public string Bar { get { return bar; } }

    public Foo(string bar) { this.bar = bar; }
}
static class Program
{
    static void Main()
    {
        DataContractSerializer dcs = new DataContractSerializer(typeof(Foo));
        MemoryStream ms = new MemoryStream();
        Foo orig = new Foo("abc");
        dcs.WriteObject(ms, orig);
        ms.Position = 0;
        Foo clone = (Foo)dcs.ReadObject(ms);
        Console.WriteLine(clone.Bar);
    }
}
Marc Gravell
Ok, that makes sense. I couldn't find any documentation on that and thought I had read that a default constructor was needed. This works great! Thanks...
Craig Wilson
this is fine if you have a simple backing property but what if the readonly property is something like public string FooBar { get {return Foo + ' ' + Bar; }} how does the datacontract serializer handle that situaion?
lomaxx
@lomaxx, well, unless you mark it `[DataMember]`, it will do nothing; but that is a read-only property, so I expect it will either ignore you or throw an exception. If you have a getter and setter, it will do whatever your code asks it to do.
Marc Gravell