数据协定序列化程序 – 如何省略集合的外部元素

如何使用Data Contract Serializer序列化没有外部元素的列表 ? 我正在使用.Net 3.5。 我有一个包含列表的类,除其他外,我希望序列化,而外部元素不符合相关的XSD:

[DataContract(Name="MyClass")] public class MyClass { ... [DataMember(Name="Parameters")] public List Parameters; ... } [DataContract(Name="Parameter")] public struct Parameter { [DataMember(Name="ValueName")]string ValueName; [DataMember(Name="Value")]int Value; public Parameter(string ValueName, int Value) { this.ValueName = ValueName; this.Value = Value; } } 

以上序列化为(假设列表中只有一个参数):

         

我想将它序列化如下:

       

使用XmlSerializer我可以通过将[XmlElement]应用于列表来完成此操作:

 [XmlElement ("Parameter")] public List Parameters; 

但是我不想使用XmlSerializer因为我的类有一些非序列化友好的属性,我希望处理那些使用[OnSerializing]属性系列的属性。

谢谢。

DataContract序列化程序不允许对生成的XML进行这种程度的控制,您必须使用XmlSerializer来实现此目的。

使用收集数据合同:

  [CollectionDataContract(Name = "MyClass", ItemName = "Parameter")] public class ParameterList : List { } 

这是实际的代码:

 public class TestSerialize { [DataContract(Name = "Parameter")] public struct Parameter { [DataMember(Name = "ValueName")] string ValueName; [DataMember(Name = "Value")] int Value; public Parameter(string ValueName, int Value) { this.ValueName = ValueName; this.Value = Value; } } [CollectionDataContract(Name = "MyClass", ItemName = "Parameter")] public class ParameterList : List { } public string Serialize(ParameterList plist) { var serializer = new DataContractSerializer(plist.GetType()); var output = new StringBuilder(); var xmlWriter = XmlWriter.Create(output); serializer.WriteObject(xmlWriter, plist); xmlWriter.Close(); return output.ToString(); } public void Serialize_produces_2Levels_of_xml() { ParameterList p = new ParameterList { new Parameter("First", 1), new Parameter("Second", 2), }; var xml = Serialize(p); } } 

如果你运行它,你将获得以下XML:

    1 First   2 Second   

下面的工作使用MessageContracts,虽然是’hack’ – 它将“MyClass”元素归属于List成员,并排除了“MyClass”的包装命名空间。

 [ServiceContract(Namespace="")] public interface IService1 { [OperationContract] MyClass GetParameters(); // TODO: Add your service operations here } [DataContract(Namespace="")] public class Parameter { [DataMember] public string ValueName { get; set; } [DataMember] public int Value { get; set; } public Parameter(string ValueName, int Value) { this.ValueName = ValueName; this.Value = Value; } } [MessageContract(IsWrapped = false, WrapperNamespace="")] public class MyClass { [MessageBodyMember(Name = "MyClass", Namespace = "")] public List Parameters { get; set; } }