Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF DataContract serialization of read-only properties?

Whenever I use WCF, I always try to make immutable classes that end up going over the wire (i.e. parameters set in constructor, properties are read-only). However, this gets in the way of WCF serialization, which demands that all properties be Public get/set (which makes sense, because it has to deserialize them)

Even in this related post, I see that their solution ended up making everything Public, which violates my sense of good programming. Is there any way around this? Do I have to just settle for this solution or something like popsicle immutability and be happy with it?

The other thing I tried was something like this, where I'd have a base class for everything and a derived class that made the set useless:

/// <summary>
/// This represents a discovered virtual-machine template that can be
/// instantiated into a RunningVirtualMachine
/// </summary>
[DataContract]
[XmlRoot("VMTemplate")]
public class VirtualMachineTemplateBase
{
    [DataMember]
    public virtual ulong SizeInBytes { get; set; }
}

/// <summary>
/// This class is the real guts of VirtualMachineTemplate that we're hiding
/// from the base class.
/// </summary>
[XmlInclude(typeof(VirtualMachineTemplateBase))]
public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
{
    ulong _SizeInBytes;
    public override ulong SizeInBytes {
        get { return _SizeInBytes; }
        set { }
    }
}
like image 864
Ana Betts Avatar asked Aug 27 '09 20:08

Ana Betts


People also ask

What is DataContract serialization?

DataContractSerializer(Type, IEnumerable<Type>) Initializes a new instance of the DataContractSerializer class to serialize or deserialize an object of the specified type, and a collection of known types that may be present in the object graph.

Is DataContract mandatory in WCF?

No, the DataContractAttribute is not required - WCF will infer serialization rules.

What is DataContract in WCF?

A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts.

What is by serialization with respect to WCF?

The process forms a sequence of bytes into a logical object; this is called an encoding process. At runtime when WCF receives the logical message, it transforms them back into corresponding . Net objects. This process is called serialization.


1 Answers

If you use the DataContractSerializer (which is the default for WCF), you can serialize anyhting that's decorated with the [DataMember] attribute - even a read-only field:

[DataContract]
public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
{
    [DataMember]
    ulong _SizeInBytes;
}

But you need to use the DataContractSerializer - not the XML serializer. The XML serializer can ONLY serialize public properties (and it will, unless you put a [XmlIgnore] on them).

The DataContractSerializer is different:

  • it doesn't need a parameter-less default constructor
  • it will only serialize what you explicitly mark with [DataMember]
  • but that can be anything - a field, a property, and of any visibility (private, protected, public)
  • it's a bit faster than XmlSerializer, but you don't get a lot of control over the shape of the XML - you only get a say in what's included

See this blog post and this blog post for a few more tips and tricks.

Marc

like image 91
marc_s Avatar answered Nov 16 '22 03:11

marc_s