![](/img/trans.png)
[英]Xml serialization: serialize list of custom classes, derived from the same base class, using base class name for elements
[英]Serialization of class derived from List<> using 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
(或其他不能序列化私有字段的類)。
請改用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; }
好的,因此Climber104的解決方案可以工作,但是我需要重新實現List
的所有方法,這使我感到自己正在重新發明輪子。
Jarek Waliszko的線程的JaredPar建議使用包裝器類。
最簡單的方法是僅出於序列化過程的目的使用它,因此我使用了受保護的內部包裝程序類。 這使我僅需幾行代碼即可實現自己的目標。
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);
}
}
}
查看該帖子,我相信它可以為您提供幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.