2010-08-07 69 views
1

我想使用DataContract序列化從列表<>派生的類。問題是我的類的屬性不會被序列化。使用DataContract從List <>派生的類的序列化

我的課:

[CollectionDataContract] /*[Serializable]*/ /*[DataContract]*/ 
public class DownloadRuleCollection : List<DownloadRule> { 

    [DataMember(EmitDefaultValue = false)] 
    public string SomeProperty { get; set; } 
    //this is, in fact, more complex, but this is enough for the example 
} 

[DataContract] 
public class DownloadRule { 
    [DataMember(EmitDefaultValue = false)] 
    public string Name { get; set; } 

    /* 
    more properties 
    ... 
    */ 
} 

測試:

static void Main(string[] args) { 

    //fill test collection with some data... 
    var col = new DownloadRuleCollection { SomeProperty = "someText" }; 

    var rule = new DownloadRule { Name = "test01" }; 
    col.Add(rule); 

    rule = new DownloadRule { Name = "test02" }; 
    col.Add(rule); 

    rule = new DownloadRule { Name = "test03" }; 
    col.Add(rule); 

    //serialize 
    Console.WriteLine("serializing"); 

    Serialize(col, "serializationTest.xml"); 

    Console.WriteLine("serialized"); 
    Console.ReadLine(); 
} 

結果:

<?xml version="1.0" encoding="utf-8"?> 
<ArrayOfDownloadRule xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1"> 
    <DownloadRule> 
    <Name>test01</Name> 
    </DownloadRule> 
    <DownloadRule> 
    <Name>test02</Name> 
    </DownloadRule> 
    <DownloadRule> 
    <Name>test03</Name> 
    </DownloadRule> 
</ArrayOfDownloadRule> 

正如你所看到的,清單的項目被序列化(和反序列化)正常,但列表本身不會被序列化。我試圖使用不同的屬性:
[Serializable],沒有改變;
[DataContract],序列化過程中拋出異常(包括集合不能使用該屬性)

順便說一句,我也序列化的私人領域,所以我不能使用XmlSerializer(不能序列化私有字段或其他類)。

回答

2

好的,所以Climber104的解決方案可以工作,但我需要重新實施所有List的方法,這讓我覺得我正在重新發明輪子。

JaredPar來自Jarek Waliszko的線程建議使用包裝類。
最簡單的就是爲了序列化過程而使用它,所以我使用了一個受保護的innner包裝類。這使我只需要幾行代碼即可實現我的目標。

public class DownloadRuleCollection : List<DownloadRule> { 

    public string SomeProperty { get; set; } 

    public void Serialize(string fileName) { 
     Serializer.Serialize(
      new DownloadRuleCollection_SerializationWrapper { 
       Collection = this, 
       SomeProperty = SomeProperty 
      }, fileName); 
    } 

    public static DownloadRuleCollection Deserialize(string fileName) { 
     var wrapper = Serializer.Deserialize<DownloadRuleCollection_SerializationWrapper>(fileName); 

     var result = wrapper.Collection; 
     result.SomeProperty = wrapper.SomeProperty; 

     return result; 
    } 

    [DataContract(Name = "DownloadRuleCollection")] 
    private class DownloadRuleCollection_SerializationWrapper { 

     [DataMember(EmitDefaultValue = false, Name = "SomeProperty", Order = 0)] 
     public string SomeProperty { get; set; } 

     [DataMember(EmitDefaultValue = false, Name = "DownloadRules", Order = 1)] 
     public DownloadRuleCollection Collection; 

    } 
} 

[DataContract] 
public class DownloadRule { 
    [DataMember(EmitDefaultValue = false)] 
    public string Name { get; set; } 
} 

public static class Serializer { 
    public static void Serialize<T>(T obj, string fileName) { 
     using(XmlWriter writer = XmlWriter.Create(fileName, new XmlWriterSettings { Indent = true })) 
      new DataContractSerializer(typeof(T)).WriteObject(writer, obj); 
    } 

    public static T Deserialize<T>(Stream stream) { 
     return (T)new DataContractSerializer(typeof(T)).ReadObject(stream); 
    } 

    public static T Deserialize<T>(string fileName) { 
     using(FileStream fs = File.OpenRead(fileName)) { 
      return Deserialize<T>(fs); 
     } 
    } 
} 
+0

優雅的代碼,謝謝! – BillW 2015-11-17 16:33:35

2

改爲使用IList。這應該正確序列化。

[CollectionDataContract] /*[Serializable]*/ /*[DataContract]*/ 
    public class DownloadRuleCollection : IList<DownloadRule> { 

下面是一個例子,我使用和完美的作品:

[DataContract(Namespace="http://schemas.datacontract.org/2004/07/InboundIntegration.HL7Messaging")] 
    public class Message { 

     public Message() { 
      InsuranceList = new List<Insurance>(); 
      MessageId = GuidComb.NewGuid(); 
     } 

     [IgnoreDataMember] 
     public Guid MessageId { get; private set; } 

     #region "Data" 
     [DataMember] 
     public string MessageTypeIndicator { get; set; } 
     [DataMember] 
     public MessageConfiguration MessageConfiguration { get; set; } 
     [DataMember] 
     public Patient Patient { get; set; } 
     [DataMember] 
     public Encounter Encounter { get; set; } 
     [DataMember] 
     public IList<Insurance> InsuranceList { get; set; } 
     #endregion 

然後保險類看起來是這樣的:

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/InboundIntegration.HL7Messaging")] 
    public class Insurance { 
     [DataMember] 
     public string ExternalPayerId { get; set; } 
     [DataMember] 
     public string PayerName { get; set; } 
     [DataMember] 
     public string GroupNumber { get; set; } 
     [DataMember] 
     public string MemberIdOfPatient { get; set; } 
     [DataMember] 
     public string PatientRelationshipToInsuredIndicator { get; set; } 
     [DataMember] 
     public string CoordinationOfBenefitsPrecedenceIndicator { get; set; } 
+1

不,這不是我所需要的。我沒有序列化'DownloadRule'類的問題,我有序列化'DownloadRuleCollection'本身的問題,尤其是它的屬性。 – Markos 2010-08-07 20:08:21

相關問題