问题描述
我正在使用 WPF 中的 DataContractSerializer 编写 XML。我需要 XML 尽可能干净(不需要反序列化回同一个应用程序),没有任何命名空间等。 这主要是有效的,但是当我的数组/列表/IEnumerables 是接口类型时,我遇到了问题。
作为最小的工作示例,我想序列化以下数据结构:
namespace HR
{
public interface IEmployee
{
string FirstName { get; }
string LastName { get; }
}
[DataContract(Namespace = "")]
[KNownType(typeof(Employee))]
public class Employee : IEmployee
{
public Employee(string firstName,string lastName)
{
FirstName = firstName;
LastName = lastName;
}
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
}
namespace Business
{
[DataContract(Namespace ="")]
public class Company
{
[DataMember]
public string CompanyName { get; set; }
[DataMember]
public IEmployee CEO { get; set; }
[DataMember]
public IEnumerable<IEmployee> Employees;
}
}
我的序列化方式如下:
namespace Program
{
static void Main(string[] args)
{
Employee jimApple = new Employee("Jim","Apple");
Employee bob = new Employee("Bob","the Builder");
Company company = new Company
{
CEO = jimApple,Employees = new List<Employee> { jimApple,bob }
};
var outputPath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),"Test.xml");
Stream outputStream = new System.IO.FileStream(outputPath,FileMode.Create);
using (var writer = XmlWriter.Create(outputStream,new XmlWriterSettings { Indent = true }))
{
var serializer = new DataContractSerializer(typeof(Company));
serializer.WriteObject(writer,company);
}
}
}
写出来的内容如下:
<?xml version="1.0" encoding="utf-8"?>
<Company xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CEO xmlns="" i:type="Employee">
<FirstName>Jim</FirstName>
<LastName>Apple</LastName>
</CEO>
<CompanyName i:nil="true" />
<Employees xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:anyType xmlns="" i:type="Employee">
<FirstName>Jim</FirstName>
<LastName>Apple</LastName>
</d2p1:anyType>
<d2p1:anyType xmlns="" i:type="Employee">
<FirstName>Bob</FirstName>
<LastName>the Builder</LastName>
</d2p1:anyType>
</Employees>
</Company>
现在差不多好了,但我需要将 <d2p1:anyType xmlns="" i:type="Employee">
行简单地看起来像 <Employee>
。我也更喜欢去掉 xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
。
我一直在研究 DataContractResolver 类来做这种事情,但没有运气。有什么办法可以实现上述目标吗?
解决方法
您应该考虑使用自定义集合类型并使用 CollectionDataContract
属性对其进行修饰:
[DataContract(Namespace = "")]
public class Company
{
[DataMember]
public string CompanyName { get; set; }
[DataMember]
public IEmployee CEO { get; set; }
[DataMember]
public EmployeeCollecion Employees;
}
[CollectionDataContract(ItemName = "Employee",Namespace = "")]
public class EmployeeCollecion : List<Employee>
{
public EmployeeCollecion() : base() { }
public EmployeeCollecion(int capacity) : base(capacity) { }
public EmployeeCollecion(IEnumerable<Employee> collection) : base(collection) { }
}
这可能是您使用 DataContractResolver
的程度。如果您需要自定义序列化并且“不需要反序列化回同一个应用程序”,那么您自己进行序列化似乎更容易。