反序列化和构造函数关系

时间:2015-06-19 12:57:02

标签: c# xml deserialization

我不知道为什么我无法在网上轻松快速查找,但我想知道反序列化对象的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

为什么不这样做?

3 个答案:

答案 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将构造对象(通过调用无参数构造函数,如果没有,则抛出异常)。然后使用一些反射魔法逐个填充属性。

那会发生什么:

  1. 调用构造函数,您可以在其中设置AppPoolSite的值。

  2. xml中有Site属性,它被反序列化并分配。

  3. 但xml中没有AppPool,因此没有任何变化,其值保持不变(<{1}})。

  4. null null,您不应在构造函数中设置其值。如果在xml中丢失,它将保持不变。

    以下是一种可能的解决方案:

    AppPool