2010-07-01 10 views
9

J'utilise actuellement des classes wrapper pour mes DataSets, afin d'implémenter la sérialisation personnalisée. Je voudrais utiliser DataContractSerializer (plus comme avoir à l'utiliser), mais toujours en charge la sérialisation personnalisée. Le problème est que les attributs [DataContract] et [Serializable] ne semblent pas s'entendre si bien ... comment pourrais-je remplacer la sérialisation, et le soutien BOTH DataContract & Sérialisation ISerializable? Le code de la classe DataSet emballage est présenté ici:Sérialisation personnalisée avec DataContractSerializer

[Serializable()]  
[System.Runtime.InteropServices.ComVisible(false)] 
public class TestDatasetWrapper : TestDataSet, ISerializable 
{ 
    public TestDatasetWrapper() 
     : base() 
    {} 

    protected TestDatasetWrapper(SerializationInfo info, StreamingContext context) 
    { 
     SerializationHelper.DeserializeTypedDataSet(info, this); 
    } 

    public override void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     SerializationHelper.AddTypedDataSetObjectData(info, this); 
    } 
} 

Merci!

Répondre

12

DataContractAttribute et SerializableAttribute peuvent être utilisés ensemble. Le bonus ici est, vous n'avez pas besoin d'utiliser des sérialiseurs séparés non plus. Le DataContractSerialzer est un XmlObjectSerializer, qui lui-même prend en charge [Serializable]. Par exemple:

[Serializable] 
public class TestClass 
{ 
    public string Name { get; set; } 
} 

{ 
    var formatter = new DataContractSerializer(typeof(TestClass)); 
    using (var stream = new MemoryStream()) 
    { 
     var instance = new TestClass { Name = "Matt" }; 
     formatter.WriteObject(stream, instance); 

     stream.Seek(0, SeekOrigin.Begin); 

     var second = (TestClass) formatter.ReadObject(stream); 
     Console.WriteLine(second.Name); 
    } 
} 

SORTIE: "Matt"

En utilisant juste un SerializableAttribute attribuons nous pouvons avec succès et serialise deserialise un objet en utilisant DataContractSerializer ...

En utilisant ISerializable, nous pouvons faire la même chose:

[Serializable] 
public class TestClass2 : ISerializable 
{ 
    public TestClass2() { } 
    protected TestClass2(SerializationInfo info, StreamingContext context) 
    { 
     Name = info.GetString("name").ToUpper(); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("name", Name); 
    } 

    public string Name { get; set; } 
} 

{ 
    var formatter = new DataContractSerializer(typeof(TestClass2)); 
    using (var stream = new MemoryStream()) 
    { 
     var instance = new TestClass2 { Name = "Matt" }; 
     formatter.WriteObject(stream, instance); 

     stream.Seek(0, SeekOrigin.Begin); 

     var second = (TestClass2)formatter.ReadObject(stream); 
     Console.WriteLine(second.Name); 
    } 
} 

SORTIE: "MATT"

Et avec un DataContractAttribute:

[DataContract, Serializable] 
public class TestClass3 
{ 
    public int Age { get; set; } 

    [DataMember] 
    public string Name { get; set; } 
} 

{ 
    var formatter = new DataContractSerializer(typeof(TestClass3)); 
    using (var stream = new MemoryStream()) 
    { 
     var instance = new TestClass3 { Name = "Matt", Age = 26 }; 
     formatter.WriteObject(stream, instance); 

     stream.Seek(0, SeekOrigin.Begin); 

     var second = (TestClass3)formatter.ReadObject(stream); 
     Console.WriteLine(second.Name); 
     Console.WriteLine(second.Age); 
    } 
} 

SORTIE: "Matt"

SORTIE: 0

Lorsque le DataContractSerializer rencontre un type avec un DataContractAttribute , il utilisera cela au lieu de passer la sérialisation à son type de base, qui gère les SerializableAttribute et ISerializable int les erfaces.

Si vous rencontrez des problèmes, est-ce avec la sérialisation, ou avec la désérialisation, ou les deux?

+1

Diminué parce que? –

+0

Il semble que la ligne de signature de la fonction manque à vos trois échantillons. – dotNET