Mono WCF Advent Day 4: Message and data contract

| 1 Comment | No TrackBacks

Until today I have carefully avoided any use of complex data transfer than mere string. Our WCF stack is however ready to use complex data than just a string.

Data contract serialization

Messaging system is tied to message serialization system. WCF has "data contract" as its own data serialization framework. Objects that are attributed as [DataContractAttribute] are serialized in its own manner i.e. only fields and properties attributed as [DataMemberAttribute] are written to the serialization output.

A simple usage example:

[DataContract]
public class UserInfo
{
  [DataMember]
  public string UserName { get; set; }
  [DataMember] // whoa, are you planning to send it via SOAP?
  public string Password { get; set; }

  public string Annotation { get; set; }
}
In the example ablve, only UserName and Password will be serialized. Data contract is actually sort of fake, you can serialize and deserialize non-datacontract objects. For example,
  • - Some types are serialized as "primitive". For example, XmlQualifiedName, Guid, UniqueId, DateTimeOffset, TimeSpan ...
  • - [Serializable] objects are serialized only by its fields. You can use System.Net.IPAddress. (It is actually used in peer-to-peer connection internals.) [UPDATE] this is not working in moonlight 2.0. It needs some backporting.[/UPDATE]
  • - By default, public fields and properties are serialized, unless it is marked as [IgnoreDataMember]. It should cover large amount of the classes in .NET land.
We support DataContractSerializer, while we don't support "NetDataContractSerializer" which is an alternative serializer in .NET WCF to support complete(?) CLR object serialization (yet). There is actually another data contract serializer. I'll revisit it in later days.

Serialization output is written to XmlDictionaryWriter, which is a derived implementation of XmlWriter, and deserialization input is read from XmlDictionaryReader, which is based on XmlReader. While they are "XML" reader and writer, anything that is based on XmlReader and XmlWriter should work. I will introduce JSON reader and writer in later days.

Message

In WCF, messages in the client-server system is represented as System.ServiceModel.Channels.Message class. A Message is originally mapped to the notion of a SOAP Envelope. A Message contains a set of Headers, Body (again, SOAP Header and SOAP Body), and message Properties (it is not transmitted). In an operation contract, Message can be used as its input and output, like:

[ServiceContract]
public interface IRequestAnything
{
    [OperationContract]
    Message Request (Message input);
}

In this contract you can send and receive any kind of Messages. If your input and/or output do not fit any of the supported serialization strategy and you are willing to handle them by yourself, it is useful.

A Message can be created by a lot of CreateMessage() method overloads. For example, CreateMessage(messageVersion, soapAction, bodyXmlReader) is useful to create a message from server replies, and CreateMessage(MessageVersion, soapAction, bodyObject) is useful to create a message from a serializable object (for both cases you wouldn't have to do it usually though). WCF internally uses those methods to create and read messages.

A Message also has a set of "properties". They do not show up in outputs, but may control the message transfer, or serialization. For example, you can use HttpRequestMessageProperty object which controls HTTP transport, for example by adding your own HTTP request header items.

Message contract

The last one I explain here is sorta confusing; you can sort of control the actual creation of messages by using "message contract", represented as [MessageContract] attribute. It is placed on sort of a data class where instances of it are to be serialized and deserialized.

Under message contract, members of the class with [MessageHeader] attribute are processed as message Headers, and members with [MessageBody] become the Body of the message. They can be any type and serialized using data contract serializer explained above. So, its' sort of confusing, but the usage is rather about message serialization, not arbitrary object serialization.

Missing stuff

In mono 2.6, I haven't finished (actually even haven't started) working on message fault contract support (such as FaultContractInfos). Things like MessageFault should work, but any further complicated contract stuff is left untouched yet.

No TrackBacks

TrackBack URL: http://veritas-vos-liberabit.com/monogatari/mt-tb.cgi/88

1 Comment

Was stuck with some problems and issues regarding programming and making notes about my class and this really helped me alot as I incidental came to this site thanks you.
My Blog : tunique femme 

Leave a comment