Skip to content
Tags

ADO.NET: XMLSerialization of extended DataTable

October 18, 2009

Before 1,5 year I worked on the project, where we move all communication logic from .NET Remoting to WCF. In the architecture of the project our common transportation object is derived from Data Table. Due to some business rules this class has some additional fields. In .NET Remoting serialization of that kind of object works perfectly, but in WCF these additional fields isn’t serialized. The problem is due to changes serialization mechanism. Instead of binary serialization in .NET Remoting, in WCF serialization is XML based. In trying to solve this issue I created a post in MSDN Forums. Despite of that I found out the solution. This article explain my solution and give the community more clear view how to do it, instead of looking my old post in MSDN.

Lets say that we have this class that derives Data Table:

public class WcfDataTable : DataTable

{

    private string _ServerName;

 

    public WcfDataTable()

        : base()

    { }

 

    public WcfDataTable(string tableName)

        : base(tableName)

    { }

 

    public string ServerName

    {

        get { return this._ServerName; }

        set { this._ServerName = value; }

    }

}

 

 

Lets serialize instance of this class using XMLSerializer:wcf_table_screen

As you can see I’m creating dummy WcfDataTable object, which I’m cloning using xml serialization and deserialization. The cloned object is not identical with the original object, because this additional field is not initialized with the original value (it’s null). The existing xml serialization doesn’t catch the new field in the class. To make possible this field for xml serialization we should override the existing xml serialization, but how to do it? The solution is really simple. You have to implement the interface IXmlSerializable with explicit override of all its methods.

public class WcfDataTable : DataTable, IXmlSerializable

{

    private string _ServerName;

 

    public WcfDataTable()

        : base()

    { }

 

    public WcfDataTable(string tableName)

        : base(tableName)

    { }

 

    public string ServerName

    {

        get { return this._ServerName; }

        set { this._ServerName = value; }

    }

 

    void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)

    {

        base.ReadXmlSchema(reader);

 

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(string));

        this._ServerName = xmlSerializer.Deserialize(reader) as string;

 

        base.ReadXml(reader);

    }

 

    void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)

    {

        base.WriteXmlSchema(writer);

 

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(string));

        xmlSerializer.Serialize(writer, this._ServerName);

 

        base.WriteXml(writer, XmlWriteMode.DiffGram);

    }

}

 

To do this workaround we have to override WriteXml and ReadXml method explicitly. The methods ReadXmlSchema and WriteXmlSchema are used to read and write the schema of data table, then we can read or write our data. Hence we can write/read our new field and then to invoke basic logic for serialization or deserializtion. So we reach our goal:

 

wcf_table_screen_done

After this workaround you can see that our new field is serialized and deserialized successfully.

Advertisement

From → Articles

2 Comments
  1. Igor permalink

    Svetlin,

    Thank you for the article, but I would like to ask you this question “Why do you need to pass a Data Table via WCF”.
    You do realize that it will make your service unavailable for any non-.NET client?

    Cheers,
    Igor

    • First thanks for the question, Igor. As I mentioned in the article this is real world example from my professional life as software developer. The case is that we migrated existing application from .NET Remoting to WCF due to marketing requirements (the client decided to use WCF as marketing strategy to sell the product as safe and secure product). The product doesn’t support third party clients (like non-.NET applications), because it doesn’t provide external service for other systems.It is enterpise system that includes several applications and supports only its clients:

      – Desktop Think Client deployed via Click Once
      – WCF (.NET Remoting) Windows Service, which is the client’s server
      – Schedule Windows Service
      – ASP.NET WebSite
      – Mobile Application Client

      Some additinal words about DataTable and WCF:
      1. I don’t recommend using DataTable as transporation object in WCF or .NET Remoting, because this kind of object is heavy for serialization/deserialization and it has big size.
      2. If you are using DataTable to transport data via WCF you must specify the name of the table when you create it, otherwise xml serialization will throw exception.

      I hope that you understand my point of view. If you have any other questions, feel free to ask me. Good luck.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.