C# 为不可序列化的属性生成 XML
C# generate XML for non-serializable properties
我有很多 classes,我想导出为 XML 供其他应用程序使用。我要导出的属性没有 setter 并且 classes 没有没有属性的构造函数,因为我不想在我的代码中出现这种行为。因此,我似乎无法对这些 class 和属性使用 (XML) 序列化,即使我确实想将其导出到 XML。不过,我不需要反序列化,因为 XML 的序列化只用于导出。
我试过 XML 序列化,但看起来这真的只支持 classes 可以双向使用(序列化和反序列化),这使得我的 classes不适用。 https://docs.microsoft.com/en-us/dotnet/standard/serialization/introducing-xml-serialization
显然,我可以为每个 class 制作可序列化版本,但手动执行此操作需要我在更新可序列化的原始 classes 后手动检查classes。此外,我需要为每个 class 编写要转换为可序列化版本的代码。
有没有一种方法可以利用 XML 序列化的优势来解决所有关于 XML 的模糊问题,而不需要将 classes 反序列化?或者对于导出这些 class 和属性的 XML 的简单方法,您有任何其他建议吗?
有一点非常简单的指导适用于几乎每个序列化器,无论格式如何(xml、json、protobuf 等),实施细节等:
- 如果您的类型模型恰好 1:1 适合序列化程序,那就太好了!使用它!
- 否则,不要尝试;创建一个完全独立的模型,该模型纯粹用于序列化;形状和行为应该 完全 序列化器需要什么才能得到你想要的结果;然后根据需要在两个模型(您的域模型和序列化模型)之间进行映射
关于 "many serializers allow a custom serializer API" 有一个警告,但根据我的经验,通常不值得这样痛苦,切换到单独的序列化模型更好主意。这适用于 尤其是 在 XmlSerializer
的情况下,因为 IXmlSerializable
几乎不可能完全手动实现。
所以;在这里明确;如果问题是你的类型缺少正确的构造函数和 属性 设置器来与 XmlSerializer
一起工作:创建一个 具有这些东西 的新模型,并在两者之间填充他们。
DataContractSerializer 可以在没有默认构造函数的情况下序列化 classes。
您必须用 DataContractAttribute 标记 class 才能这样做。此外,要序列化的属性需要 setters。 setter 可能是私有的,但 setter 确实必须存在:
[DataContract] // Need this to serialize classes without default constructor.
public class Person
{
public Person(string name, DateTime dob)
{
this.Name = name;
this.DateOfBirth = dob;
}
[DataMember] // Need this to serialize this property
public string Name { get; private set; } // Need setter for serializer to work
[DataMember]
public DateTime DateOfBirth { get; private set; }
}
用法:
var person = new Person("Jesse de Wit", new DateTime(1988, 5, 27));
var serializer = new DataContractSerializer(typeof(Person));
using (var stream = new MemoryStream())
{
serializer.WriteObject(stream, person);
}
我有很多 classes,我想导出为 XML 供其他应用程序使用。我要导出的属性没有 setter 并且 classes 没有没有属性的构造函数,因为我不想在我的代码中出现这种行为。因此,我似乎无法对这些 class 和属性使用 (XML) 序列化,即使我确实想将其导出到 XML。不过,我不需要反序列化,因为 XML 的序列化只用于导出。
我试过 XML 序列化,但看起来这真的只支持 classes 可以双向使用(序列化和反序列化),这使得我的 classes不适用。 https://docs.microsoft.com/en-us/dotnet/standard/serialization/introducing-xml-serialization
显然,我可以为每个 class 制作可序列化版本,但手动执行此操作需要我在更新可序列化的原始 classes 后手动检查classes。此外,我需要为每个 class 编写要转换为可序列化版本的代码。
有没有一种方法可以利用 XML 序列化的优势来解决所有关于 XML 的模糊问题,而不需要将 classes 反序列化?或者对于导出这些 class 和属性的 XML 的简单方法,您有任何其他建议吗?
有一点非常简单的指导适用于几乎每个序列化器,无论格式如何(xml、json、protobuf 等),实施细节等:
- 如果您的类型模型恰好 1:1 适合序列化程序,那就太好了!使用它!
- 否则,不要尝试;创建一个完全独立的模型,该模型纯粹用于序列化;形状和行为应该 完全 序列化器需要什么才能得到你想要的结果;然后根据需要在两个模型(您的域模型和序列化模型)之间进行映射
关于 "many serializers allow a custom serializer API" 有一个警告,但根据我的经验,通常不值得这样痛苦,切换到单独的序列化模型更好主意。这适用于 尤其是 在 XmlSerializer
的情况下,因为 IXmlSerializable
几乎不可能完全手动实现。
所以;在这里明确;如果问题是你的类型缺少正确的构造函数和 属性 设置器来与 XmlSerializer
一起工作:创建一个 具有这些东西 的新模型,并在两者之间填充他们。
DataContractSerializer 可以在没有默认构造函数的情况下序列化 classes。
您必须用 DataContractAttribute 标记 class 才能这样做。此外,要序列化的属性需要 setters。 setter 可能是私有的,但 setter 确实必须存在:
[DataContract] // Need this to serialize classes without default constructor.
public class Person
{
public Person(string name, DateTime dob)
{
this.Name = name;
this.DateOfBirth = dob;
}
[DataMember] // Need this to serialize this property
public string Name { get; private set; } // Need setter for serializer to work
[DataMember]
public DateTime DateOfBirth { get; private set; }
}
用法:
var person = new Person("Jesse de Wit", new DateTime(1988, 5, 27));
var serializer = new DataContractSerializer(typeof(Person));
using (var stream = new MemoryStream())
{
serializer.WriteObject(stream, person);
}