我正在尝试序列化从List<>派生的类使用DataContract。问题是我的类的属性不会被序列化。
我的课程:
[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>
如您所见,List的项目已正确序列化(和反序列化),但List本身不会被序列化。我试图使用不同的属性:
[Serializable]
,没有变化;
[DataContract]
,在序列化期间抛出异常(集合无法使用此属性)
btw我正在序列化私有字段,所以我不能使用XmlSerializer
(或其他不能序列化私有字段的类)。
答案 0 :(得分: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 :(得分:2)
好的,所以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);
}
}
}
答案 2 :(得分:1)
检查帖子,我相信它可以帮到你