Introduction
WCF serialization rely on the Data Contract and Data Member decoration
This post discuss one simple trick that available in cases that you having your own data contract that holding data members that does not been decorated for the WCF serialization
This trick will work as long as you reuse the same assembly of the data contract both on the client and service sides
There some other techniques for advance serialization which will beyond the scope of this post
you can find the post code in here
Our Test Case
In our test case we will have data contract that has data member of type DataTable
Note: you do not need this trick for typed data table, it does serialized well
Having the following service:
[ServiceContract]
public interface IMyService
{
[OperationContract]
CustomEntity GetData ();
}
[DataContract]
public class CustomEntity
{
[DataMember]
public DataTable Table { get; set; }
}
Notice that we try to have data contract that having data member which does not design to be serialized using WCF serialization (because DataTable does not decorate with data contract attribute)
The trick is very simple and it can be assign for any similar cases
it simply using the data contract serialization processing with little twist
We will serialize the DataTable indirectly using private data member which won’t expose by our Custom Entity API so the consumer of our Custom Entity won’t e aware of it, still the WCF will use it during the serialization process
Steps needed to achieve our goal
- Remove the data member decoration from the Table property
- Add custom private data member that will handle the serialization process
- We need one member to serialize the DataTable schema
- And other member to serialize the DataTable data (the data deserialization must occur after the schema deserialization completed)
Our data contract should look like the following one
[DataContract]
public class CustomEntity
{
[DataMember (Order=0)]
private byte[] TableSchemaSerialization
{
get
{
// the folowing operation will occur during the WCF serializing
var srm = new MemoryStream ();
this.Table.WriteXmlSchema (srm);
return srm.ToArray ();
}
set
{
// the folowing operation will occur during the WCF deserializing
this.Table = new DataTable ();
var srm = new MemoryStream (value);
this.Table.ReadXmlSchema (srm);
}
}
[DataMember (Order=1)]
private byte[] TableDataSerialization
{
get
{
// the folowing operation will occur during the WCF serializing
var srm = new MemoryStream ();
this.Table.WriteXml (srm);
return srm.ToArray ();
}
set
{
// the folowing operation will occur during the WCF deserializing
var srm = new MemoryStream (value);
this.Table.ReadXml (srm);
}
}
//[DataMember]
public DataTable Table { get; set; }
}
Conclusion
As long as we reusing the data contract at both service and client sides
We can build our data contract to intercept the serialization process without changing the data contract API