3 votes

Pourquoi ma DataTable ne se sérialise-t-elle pas correctement lorsque les noms des colonnes contiennent des espaces ?

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

0voto

banging Points 2442

Vous devez définir l'attribut Serializable à votre classe d'objet personnalisée

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

Voici un article pour vous http://www.codeproject.com/Articles/1789/Object-Serialization-using-C

0voto

Isaac Points 31

Non seulement vous devez utiliser l'attribut Serializable, mais vous devez également mettre en œuvre IXmlSerializable pour que le type personnalisé soit sérialisé correctement dans un ensemble de données. Mes jeux de données revenaient avec des colonnes vides jusqu'à ce que j'implémente IXmlSerializable.

Les UDT doivent prendre en charge la conversion vers et depuis le type de données xml en se conformant au contrat de sérialisation XML. L'espace de nom System.Xml.Serialization contient des classes qui sont utilisées pour sérialiser des objets en documents ou flux au format XML. Vous pouvez choisir d'implémenter la sérialisation xml en utilisant l'interface IXmlSerializable, qui fournit un formatage personnalisé pour la sérialisation et la désérialisation XML.

En plus d'effectuer des conversions explicites de UDT à xml, la sérialisation XML vous permet de :

Utilisation de Xquery sur les valeurs des instances UDT après conversion au type de données xml.

Utiliser les UDT dans les requêtes paramétrées et les méthodes Web avec les services Web XML natifs dans SQL Server.

Utilisez les UDT pour recevoir un chargement en vrac de données XML.

Sérialise les DataSets qui contiennent des tables avec des colonnes UDT.

Les UDT ne sont pas sérialisées dans les requêtes FOR XML. Pour exécuter une requête FOR XML qui affiche la sérialisation XML des UDT, convertissez explicitement chaque colonne UDT au type de données xml dans l'instruction SELECT. Vous pouvez également convertir explicitement les colonnes en varbinaire, varchar ou nvarchar.

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

Avantages de l'utilisation de IXmlSerializable http://technet.microsoft.com/en-us/library/ms131082.aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X