我们已经建立了previously,DCS按字母顺序序列化/反序列化对象。然而,经过进一步调查后,我发现这不是完全真实。
如果我们有这样的结构:
[DataContract]
public class Content
{
[DataMember]
public string Title;
[DataMember]
public string Slug;
[DataMember]
public string Description;
}
[DataContract]
public class TextContent : Content
{
[DataMember]
public string Text;
}
并且有一个TextContent类型的对象要序列化,DCS会这样做:
<Content i:type="TextContent" ...>
<Description>desc</Description>
<Slug>some-slug</Slug>
<Title>content title</Title>
<Text>some content</Text>
</Content>
正如您所看到的,继承类的属性附加到序列化XML片段的末尾,即使它应该在Title之前。 DCS不会检查组合属性并重新排序。 当我在Title元素前面手动添加Text元素时,我注意到了这一点,反序列化只是不想工作。这就是为什么我执行了一个新对象的序列化并想出了这个。
我的问题是:
答案 0 :(得分:2)
基本类型始终是订单中的第一个。您可以根据Order
属性的DataMember
属性定义对象的序列化属性的顺序(请参阅http://msdn.microsoft.com/en-us/library/ms729813.aspx)
答案 1 :(得分:0)
有NetDataContractSerializer,但它和DCS之间的唯一区别是它支持客户端和服务器之间的类型共享,但是你失去了向前兼容性,因为双方都必须序列化/反序列化为相同的类型。
在codeplex上还有协议缓冲区的C#包装器: http://code.google.com/p/protobuf-net/
我自己没有尝试过,但它应该更快更轻巧。至于你的实际问题:
答案 2 :(得分:0)
如果您需要能够序列化以匹配外部架构,那么您显然不应该使用DataContractSerializer
。这不是它的用途。
您可以使用XmlSerializer
,旨在让您更好地控制序列化的XML,或实现IXmlSerializable
,并获得对XML的完全控制,或者您可以编写自己的自定义使用LINQ to XML进行序列化。这将让您完全按照您的提及 - 以不同方式序列化相同的数据。例如:
internal class Person
{
internal string Name { get; set; }
internal string Telephone { get; set; }
internal Address HomeAddress { get; set; }
internal Address WorkAddress { get; set; }
}
internal class Address
{
internal string Line1 { get; set; }
internal string Line2 { get; set; }
internal string City { get; set; }
internal string State { get; set; }
internal string PostalCode { get; set; }
}
private static void Main()
{
var person = new Person
{
Name = "John Saunders",
Telephone = "something",
HomeAddress = new Address
{
Line1 = "Line 1",
Line2 = "Line 2",
City = "SomeCity",
State = "SS",
PostalCode = "99999-9999",
},
WorkAddress = new Address
{
Line1 = "Line 1a",
Line2 = "Line 2a",
City = "SomeCitay",
State = "Sa",
PostalCode = "99999-999a",
},
};
XDocument personWithElements = SerializeAsElements(person);
personWithElements.Save("PersonWithElements.xml");
XDocument personWithAttributes = SerializeAsAttributes(person);
personWithAttributes.Save("PersonWithAttributes.xml");
}
private static XDocument SerializeAsElements(Person person)
{
return new XDocument(
new XElement("Person",
new XElement("Name", person.Name),
new XElement("Telephone", person.Telephone),
SerializeAddressAsElements(person.HomeAddress, "HomeAddress"),
SerializeAddressAsElements(person.WorkAddress, "WorkAddress"))
);
}
private static XElement SerializeAddressAsElements(Address address, string elementName)
{
return new XElement(elementName,
new XElement("Line1", address.Line1),
new XElement("Line2", address.Line2),
new XElement("City", address.City),
new XElement("State", address.State),
new XElement("PostalCode", address.PostalCode)
);
}
private static XDocument SerializeAsAttributes(Person person)
{
return new XDocument(
new XElement("Person",
new XAttribute("Name", person.Name),
new XAttribute("Telephone", person.Telephone),
SerializeAddressAsAttributes(person.HomeAddress, "HomeAddress"),
SerializeAddressAsAttributes(person.WorkAddress, "WorkAddress"))
);
}
private static XElement SerializeAddressAsAttributes(Address address, string elementName)
{
return new XElement(elementName,
new XAttribute("Line1", address.Line1),
new XAttribute("Line2", address.Line2),
new XAttribute("City", address.City),
new XAttribute("State", address.State),
new XAttribute("PostalCode", address.PostalCode)
);
}
PersonWithElements:
<?xml version="1.0" encoding="utf-8"?>
<Person>
<Name>John Saunders</Name>
<Telephone>somethine</Telephone>
<HomeAddress>
<Line1>Line 1</Line1>
<Line2>Line 2</Line2>
<City>SomeCity</City>
<State>SS</State>
<PostalCode>99999-9999</PostalCode>
</HomeAddress>
<WorkAddress>
<Line1>Line 1a</Line1>
<Line2>Line 2a</Line2>
<City>SomeCitay</City>
<State>Sa</State>
<PostalCode>99999-999a</PostalCode>
</WorkAddress>
</Person>
PersonWithAttributes:
<?xml version="1.0" encoding="utf-8"?>
<Person Name="John Saunders" Telephone="somethine">
<HomeAddress Line1="Line 1" Line2="Line 2" City="SomeCity" State="SS" PostalCode="99999-9999" />
<WorkAddress Line1="Line 1a" Line2="Line 2a" City="SomeCitay" State="Sa" PostalCode="99999-999a" />
</Person>