Normalement, j'essaie de rester à l'écart de DataSet
et DataTable
mais nous avons actuellement une exigence pour laquelle il semble judicieux de les utiliser.
J'ai des problèmes pour sérialiser un DataTable
lorsque le DataColumn
Le nom contient un espace et le type de la colonne est un type personnalisé que j'ai écrit.
Il semble que le processus de sérialisation ajoute par erreur des caractères d'échappement au nom de colonne codé, comme s'il avait été codé deux fois. Cela ne se produit que si j'utilise mon propre type comme type de données de la colonne, en utilisant la commande typeof(object)
fonctionne bien.
S'agit-il d'une caractéristique standard, et si c'est le cas, quelqu'un connaît-il un moyen de la contourner ?
L'exemple de code suivant illustre ce problème. La colonne appelée "NameWithoutSpaces" est codée comme "NameWithoutSpaces". alors que "Name With Spaces" est encodé comme "Name_x005F_x0020_With_x005F_x0020_Spaces". avec en plus x005F caractères
Lors de l'écriture du schéma, la colonne est correctement encodée en tant que "Name_x0020_With_x0020_Spaces", ce qui, je suppose, est à l'origine du problème, car cette colonne est vide lorsque les méthodes Read* sont appelées.
Selon la documentation de XmlConvert.EncodeName l'espace doit être codé avec x0020 et le 005F est utilisé comme caractère d'échappement. Ainsi, le résultat que nous obtenons semble être ce qui se passerait si le texte avait été codé deux fois par ce mécanisme.
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; }
}
}