xml 序列化 - 处理 .Net 如何序列化可为 null 的类型



默认情况下,.Net 最终将 xml 序列化为空的类型到如下所示的节点中

<SomeNode p3:nil="true" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance" />

不幸的是,鉴于我正在序列化的对象模型有很多很多很多的空值,我最终得到了一个非常大的 xml 文档 (185mb),而它应该小得多,完全删除了空节点 (20mb)

当我添加 Web 服务引用时,对象定义是自动生成的,因此,幸运的是它被声明为分部类,并且我能够创建自己的分部类,这些分部类添加了一堆ShouldSerialize*方法来防止序列化任何 null 值。

但是,这是相当乏味的,因为类很大,而且很多。

有没有办法使用反射来简化在运行时为所有公共属性向类中添加ShouldSerialize*方法的过程?

就像我写的,我为一些类手动做了这个,它是高度重复的,100 多个函数都看起来像这样

public bool ShouldSerializeNotes() { return Notes != null; }

谢谢-c

与 Marc 的想法类似,但更精简一些,您可以将所有类和属性名称粘贴到文本或 XML 文件中,然后将其用作使用 ShouldSerialize* 方法生成分部类的 T4 模板的输入。T4 在 VS2008 中似乎完全没有文档,但是如果您为解决方案中的文本文件提供 .tt 扩展名,它应该为您设置正确的自定义工具进行代码生成。VS2010 中正确支持所有内容。

作为一次性,您可以将属性名称写入文本文件(通过类型。GetProperties()),并使用基本工具(电子表格就足够了)来生成基本方法be属性。不复杂,但务实。当然,您需要考虑正在进行的更改。

回答提出的问题;不,不是真的(除非你实现IXmlSerializable,这是一个痛苦)。

不过,我想问的是:它必须是XML吗?我可以通过更改数据格式使其更小,具有您描述的行为(没有为空值写入数据)。这可能不是一种选择,但这似乎确实不必要地大。

我的解决方案:将属性添加到文档的根节点,如下所示:

var writer = XmlWriter.Create(...);
writer.WriteStartElement("root");
writer.WriteAttributeString("xmlns", "p3", null, @"http://www.w3.org/2001/XMLSchema-instance");

然后,XmlSerializer 不必在每个可为 null 的元素上写出命名空间。

在我的情况下,可为空的变量/元素都是字符串类型。因此,我只是执行了检查并为其分配了字符串。在空的情况下为空。通过这种方式,我摆脱了不必要的nil和xmlns属性(p3:nil="true" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance)

// Example:
myNullableStringElement = varCarryingValue ?? string.Empty
// OR
myNullableStringElement = myNullableStringElement ?? string.Empty

最新更新