数据契约序列化器——如何省略集合的外部元素
本文关键字:集合 外部 元素 何省略 契约 序列化 数据 | 更新日期: 2023-09-27 18:18:25
如何使用数据契约序列化器序列化没有外部元素的列表?我使用的是。net 3.5。我有一个类,其中包含一个列表,以及其他内容,我希望序列化它,而不使用外部元素以符合相关的XSD:
[DataContract(Name="MyClass")]
public class MyClass
{
...
[DataMember(Name="Parameters")]
public List<Parameter> 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;
}
}
以上序列化为(假设列表中只有一个参数):
<MyClass>
<Parameters>
<Parameter>
<ValueName></ValueName>
<Value></Value>
</Parameter>
</Parameters>
</MyClass>
我想序列化它如下:
<MyClass>
<Parameter>
<ValueName></ValueName>
<Value></Value>
</Parameter>
</MyClass>
使用XmlSerializer,我可以通过对列表应用[XmlElement]来做到这一点:
[XmlElement ("Parameter")]
public List<Parameter> Parameters;
然而,我不想使用XmlSerializer
,因为我的类有一些属性是不序列化友好的,我希望处理那些使用[OnSerializing]家族属性。
谢谢。
DataContract
序列化器不允许对生成的XML进行这种程度的控制,您将不得不使用XmlSerializer
来实现这一点。
下面的工作使用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<Parameter> Parameters
{
get;
set;
}
}
使用集合数据契约:
[CollectionDataContract(Name = "MyClass", ItemName = "Parameter")]
public class ParameterList : List<Parameter>
{
}
下面是实际代码:
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<Parameter>
{
}
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:
<?xml version="1.0" encoding="utf-16"?>
<MyClass xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Serialize.Test">
<Parameter>
<Value>1</Value>
<ValueName>First</ValueName>
</Parameter>
<Parameter>
<Value>2</Value>
<ValueName>Second</ValueName>
</Parameter>
</MyClass>