当列名包含空格时,为什么我的DataTable没有正确序列化?

时间:2012-03-01 14:47:18

标签: .net serialization datatable xml-serialization xml-encoding

通常情况下,我会尽量远离DataSetDataTable s,但我们目前有一个要求,它似乎有意义使用它们。

DataTable名称包含空格并且列的类型是我编写的自定义类型时,我在序列化DataColumn时遇到一些问题。

看起来序列化过程虚假地将转义字符添加到编码列名称中,就好像它已被编码两次一样。 只有当我使用自己的类型作为列的数据类型时才会发生这种情况,使用typeof(object)工作正常。

这是一个标准功能吗?如果有的话,是否有人知道它的任何方式?

以下代码示例演示了此问题。 名为“NameWithoutSpaces”的列编码为“NameWithoutSpaces” 而“带空格的名称”编码为“Name_x005F_x0020_With_x005F_x0020_Spaces” 使用额外的 x005F 字符

当写出模式时,列正确地被编码为“Name_x0020_With_x0020_Spaces”,我猜这是问题的原因,因为一旦调用了Read *方法,该列就是空白。

根据XmlConvert.EncodeName的文档,空间应使用 x0020 编码, 005F 用作escap char。 因此,我们得到的结果似乎是如果通过这种机制对文本进行了两次编码会发生什么。

namespace DataTableSerialization
{
    using System.Data;

    class Program
    {
        static void Main(string[] args)
        {
            var dataTable = CreateDataTable();

            var row1 = dataTable.NewRow();
            row1.ItemArray = new object[] { new Item {Value = "Data1"}, new Item {Value = "Data2"} };
            dataTable.Rows.Add(row1);

            dataTable.WriteXml(@"C:\datatable.xml");
            dataTable.WriteXmlSchema(@"C:\schema.xml");

            var dataTable2 = new DataTable();
            dataTable2.ReadXmlSchema(@"C:\schema.xml");
            dataTable2.ReadXml(@"C:\datatable.xml");
        }

        private static DataTable CreateDataTable()
        {
            var table = new DataTable { TableName = "Table" };

            var col1 = new DataColumn("NameWithoutSpaces", typeof(Item));
            var col2 = new DataColumn("Name With Spaces", typeof(Item));

            table.Columns.Add(col1);
            table.Columns.Add(col2);

            return table;
        }
    }

    public class Item
    {
        public string Value { get; set; }
    }
}

2 个答案:

答案 0 :(得分:0)

您必须将Serializable属性设置为自定义对象类..

[Serializable]
public class Item     
{
    public string Value { get; set; }
} 

这是给你的文章http://www.codeproject.com/Articles/1789/Object-Serialization-using-C

答案 1 :(得分:0)

您不仅应该使用Serializable属性,还需要为自定义类型实现IXmlSerializable以在数据集中正确序列化。在我实现了IXmlSerializable之前,我的数据集返回了空白列。

  

UDT必须通过符合XML序列化合同来支持与xml数据类型的转换。 System.Xml.Serialization命名空间包含用于将对象序列化为XML格式文档或流的类。您可以选择使用IXmlSerializable接口实现xml序列化,该接口为XML序列化和反序列化提供自定义格式。

     

除了执行从UDT到xml的显式转换之外,XML序列化还允许您:

     

转换为xml数据类型后,将Xquery用于UDT实例的值。

     

在参数化查询中使用UDT,在SQL Server中使用Native XML Web Services进行Web方法。

     

使用UDT接收大量XML数据。

     

序列化包含具有UDT列的表的DataSet。

     

在FOR XML查询中未对UDT进行序列化。要执行显示UDT的XML序列化的FOR XML查询,请在SELECT语句中将每个UDT列显式转换为xml数据类型。您还可以将列显式转换为varbinary,varchar或nvarchar。

http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx

使用IXmlSerializable的优点 http://technet.microsoft.com/en-us/library/ms131082.aspx