我不知道为什么我无法在网上轻松快速查找,但我想知道反序列化对象的XML表示与该对象的构造函数之间的关系是什么?
我假设它使用默认构造函数。如果是这种情况,它将在构造函数中运行代码,但在此之后不更新对象本身以反映XML?
这里有更多关于我的意思的背景......
我有一个具有两个属性的对象,它们实际上也是对象:
public class Deployment
{
public AppPoolSettings AppPool { get; set; }
public WebSiteSettings Site { get; set; }
public Deployment()
{
//the object constructors below init their internal properties as well...
this.AppPool = new AppPoolSettings();
this.Site = new WebSiteSettings();
}
}
我目前遇到的问题是,在XML中,AppPool
属性可以为null(例如,如果您要部署仅HTML的包)。序列化过程正常工作,也就是说,生成的XML只包含Site的条目,而AppPool没有条目。
但是,当我反序列化该XML时,我的Deployment
对象的AppPool属性总是被实例化并初始化...这不是XML所说的。
我做错了什么或者是因为默认构造函数?
请参阅我希望解串器按此顺序执行任务:
1-调用默认构造函数
2- XML中是否存在AppPool属性?
是的 - >填充,
不 - >设为NULL
3-网站属性是否存在于XML中?
是的 - >填充,
不 - >设置为NULL
为什么不这样做?
答案 0 :(得分:2)
我认为正确的答案是:是的,对于null属性的反直觉处理(在序列化数据中省略它们并且在反序列化时不对它们执行任何操作)是XmlSerializer
的一个特性。但是您可以覆盖该行为并强制XmlSerializer使用以下属性将空值写入XML:
public class Deployment
{
[XmlElement(IsNullable = true)]
public AppPoolSettings AppPool { get; set; }
[XmlElement(IsNullable = true)]
public WebSiteSettings Site { get; set; }
public Deployment()
{
//the object constructors below init their internal properties as well...
this.AppPool = new AppPoolSettings();
this.Site = new WebSiteSettings();
}
}
然后您将获得XML中的<AppPool xsi:nil="true" />
并预期反序列化。
答案 1 :(得分:1)
调用默认构造函数,因此分配了Site和AppPool。如果你想要它们null
,你可以试试这段代码:
public class Deployment
{
private AppPoolSettings appPool;
public AppPoolSettings AppPool
{
get { return appPool; }
set
{
// if (appPool == null)
// appPool = new AppPoolSettings();
appPool = value;
}
}
private WebSiteSettings site;
public WebSiteSettings Site
{
get { return site; }
set
{
// if (site == null)
// site = new WebSiteSettings();
site = value;
}
}
public Deployment()
{
// No instatiation anymore...
}
}
答案 2 :(得分:1)
你的期望是错误的。 XmlSerializer
将构造对象(通过调用无参数构造函数,如果没有,则抛出异常)。然后使用一些反射魔法逐个填充属性。
那会发生什么:
调用构造函数,您可以在其中设置AppPool
和Site
的值。
xml中有Site
属性,它被反序列化并分配。
但xml中没有AppPool
,因此没有任何变化,其值保持不变(<{1}})。
要null
null
,您不应在构造函数中设置其值。如果在xml中丢失,它将保持不变。
以下是一种可能的解决方案:
AppPool