我要说的第一件事,并且总是说:如果序列化现有模型变得棘手 - 甚至有点尴尬,那就停止这样做。花 2 分钟时间创建一个单独的 DTO 模型,即一个仅为序列化目的而创建的模型(实际上,甚至可能为特定的序列化程序量身定制)。现在您放置了正确的类型、正确的成员、正确的属性和正确的布局。您需要做的就是添加一些转换方法 - 静态转换运算符在这里工作得很好。所以我想说的是:创建一个ParentDto
和ChildDto
(你的名字可能会有所不同);这需要 3 分钟,而且效果很好。
现在,回到问题...
XmlSerializer
查看声明类以获取输入;对于属性和条件序列化,不:此时我们不能将它们添加到类型模型中。但还有另一种选择——你可以XmlAttributeOverrides
用来假装[XmlIgnore]
字典上有一个成员。但是,一些重要的警告:
- API使用
XmlAttributeOverrides
起来有点麻烦(参见 MSDN 示例)
- 关键是您只执行一次,然后存储和重新使用
XmlSerializer
您以这种方式创建的;基本上,如果你不这样做,它会在你每次new
序列化程序时创建一个新的动态程序集,并且程序集永远不会卸载,所以你会出血;请注意,简单用法(new XmlSerializer(someType)
等)为此具有内置缓存;但XmlAttributeOverrides
用法不
但同样,所有这些搞砸XmlAttributeOverrides
的工作不仅仅是创建一个基本的 DTO
使用示例XmlAttributeOverrides
:
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
public class Parent {
public Dictionary<string, int> WantToIgnoreThis { get; set; }
}
public class Child : Parent {
public int Foo { get; set; }
}
static class Program
{
static readonly XmlSerializer customSerializer;
static Program()
{
var xao = new XmlAttributeOverrides();
xao.Add(typeof(Parent), "WantToIgnoreThis", new XmlAttributes {
XmlIgnore = true
});
customSerializer = new XmlSerializer(typeof(Child), xao);
}
static void Main()
{
//var ser = new XmlSerializer(typeof(Child));
// ^^ this would fail
customSerializer.Serialize(Console.Out, new Child {
Foo = 123
});
}
}
特别注意该static
字段如何用于缓存序列化程序。