.net 当列名包含空格时,为什么我的DataTable不能正确序列化?

.net 当列名包含空格时,为什么我的DataTable不能正确序列化?,.net,serialization,datatable,xml-serialization,xml-encoding,.net,Serialization,Datatable,Xml Serialization,Xml Encoding,通常,我会尽量避开DataSets和DataTables,但我们目前有一个使用它们似乎有意义的需求 当DataColumn名称包含空格并且列的类型是我编写的自定义类型时,序列化DataTable会遇到一些问题 序列化过程似乎在向编码的列名中虚假地添加转义字符,几乎就像它被编码了两次一样。 只有当我使用自己的类型作为列的数据类型时,才会发生这种情况,使用typeof(object)效果很好 这是一个标准特性吗?如果是的话,有人知道它的解决方法吗 下面的代码示例演示了这个问题。 名为“NameWit

通常,我会尽量避开
DataSet
s和
DataTable
s,但我们目前有一个使用它们似乎有意义的需求

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

序列化过程似乎在向编码的列名中虚假地添加转义字符,几乎就像它被编码了两次一样。 只有当我使用自己的类型作为列的数据类型时,才会发生这种情况,使用
typeof(object)
效果很好

这是一个标准特性吗?如果是的话,有人知道它的解决方法吗

下面的代码示例演示了这个问题。 名为“NameWithoutSpaces”的列的编码方式与“NameWithoutSpaces”相同 而“带空格的名称”编码为“带空格的名称” 带有额外的x005F字符

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

根据文档,空间应使用x0020编码,005F用作字符。 因此,我们得到的结果似乎是,如果文本通过这种机制被编码两次,将会发生什么

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; }
    }
}

必须将可序列化属性设置为自定义对象类

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

这里有一篇文章供您阅读

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

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

除了执行从UDT到xml的显式转换外,xml序列化还使您能够:

转换为xml数据类型后,对UDT实例的值使用Xquery

在参数化查询中使用UDT,在SQL Server中使用原生XML Web服务的Web方法

使用UDT接收大量XML数据

序列化包含具有UDT列的表的数据集

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

使用IXmlSerializable的优点

为什么要避免这样强大的类?(删除我的答案,因为我想我误解了你问题的本质)有趣的是,它适用于更基本的类型;只有您的自定义
项目受this@Marc格雷威尔,别担心。我已经编辑过了,希望能让我的意思更清楚一点。你从来没有提到过你的具体问题。