Introduction
System.Data contains a bug which can cause it to throw an exception during serlisation or deserialisation of a DataSet which contains a column that uses System.Object as its .NET type.
The bug manifests itself in two known scenarios:
- Serialising a DataSet containing a column of type System.Object using a System.Xml.XmlTextWriter instance created via the static Create method; this throws a System.ArgumentException.
- Deserialising a DataSet containing a column of type System.Object after having successfully passed it across the wire via Windows Communication Foundation (WCF) using netTcp binding; this throws a System.Data.DataException.
I reported the bug to Microsoft back in 2007 whilst using .NET 2.0 and 3.0. At the time was told "it's definitely in our system for a Post Orcas release". The bug still exists in .NET Framework 3.5 SP1, although I haven't checked any of the .NET 4.0 betas yet.
This post covers the first scenario you might come across – simply serialising the DataSet with an XmlTextWriter. I'll do a follow-up next week covering the second scenario.
Reproducing the Bug
To demonstrate this behaviour we're going to need a DataSet with a System.Object column, and we're going to need to populate it with some data.
static System.Data.DataSet CreateAndPopulateDataSet() { // create a DataSet containing two columns: a string (Key) and an object (Value) System.Data.DataSet dataSet = new System.Data.DataSet(); System.Data.DataTable dataTable = dataSet.Tables.Add(); dataTable.Columns.Add("Key", typeof(string)); dataTable.Columns.Add("Value", typeof(object)); // add two rows, one containing an integer Value, and one containing a string Value dataTable.LoadDataRow(new object[] { "foo", 42 }, true); dataTable.LoadDataRow(new object[] { "bar", "Hello World" }, true); // return the DataSet return dataSet; }