3

通常、私はDataSets とDataTables を避けるようにしていますが、現在、それらを使用することが理にかなっていると思われる要件があります。

名前にスペースが含まれていて、列の型が私が書いたカスタム型であるDataTable場合、 a のシリアライズに問題があります。DataColumn

シリアル化プロセスが、エンコードされた列名に誤ってエスケープ文字を追加しているようです。まるで 2 回エンコードされたかのようです。列のデータ型として独自の型を使用した場合にのみ発生し、正常にtypeof(object)動作します。

これは標準機能ですか?もしそうなら、誰かがそれを回避する方法を知っていますか?

次のコード サンプルは、この問題を示しています。「NameWithoutSpaces」という列は「NameWithoutSpaces」と同じようにエンコードされますが、「Name With Spaces」は余分なx005F文字を含む「Name_x005F_x0020_With_x005F_x0020_Spaces」としてエンコードされます。

スキーマを書き出すと、列は「Name_x0020_With_x0020_Spaces」として正しくエンコードされます。これは、Read* メソッドが呼び出されるとこの列が空白になるため、問題の原因であると推測されます。

XmlConvert.EncodeNameのドキュメントによると、スペースはx0020でエンコードする必要があり、005Fはエスケープ文字として使用されます。したがって、得られた結果は、テキストがこのメカニズムによって 2 回エンコードされた場合にどうなるかのようです。

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

2 に答える 2

0

Serializable属性をカスタムオブジェクトクラスに設定する必要があります。

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

これがあなたのための記事ですhttp://www.codeproject.com/Articles/1789/Object-Serialization-using-C

于 2012-04-24T20:03:10.197 に答える
0

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 列を持つテーブルを含む DataSet をシリアル化します。

FOR XML クエリでは、UDT はシリアル化されません。UDT の XML シリアル化を表示する FOR XML クエリを実行するには、SELECT ステートメントで各 UDT 列を xml データ型に明示的に変換します。列を varbinary、varchar、または nvarchar に明示的に変換することもできます。

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

IXmlSerializable を使用する利点 http://technet.microsoft.com/en-us/library/ms131082.aspx

于 2012-08-17T21:02:12.713 に答える