2015-06-19 2 views
2

Я не знаю, почему я не могу найти быстрый быстрый поиск этого в Интернете, но мне было интересно, что такое отношения между десериализацией представления 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 может быть нулевым (скажем, если вы развертываете только пакет HTML). Процедура сериализации работает правильно, т. Е. Получившийся XML содержит только запись для сайта, а для AppPool - никакой записи.

Однако, когда я десериализую этот XML-объект, свойство AppPool моего объекта Deployment всегда создается и инициализируется ... это не то, что говорит XML.

Я делаю что-то неправильно или это действительно просто из-за конструктора по умолчанию?

См Я бы ожидал, что десериализатор для выполнения задач в следующем порядке:
1- вызова по умолчанию конструктор
2- ли AppPool свойство существует в XML?
              Да - > заполняющая,
              Нет - > Установите в NULL
3- Существует ли свойство сайта в XML?
              Да - > заполняющая,
              Нет - > Установите в NULL

Почему он не делает этого?

ответ

2

Я считаю, что правильный ответ: да, противоречащей обработку нулевых свойств (опуская их в последовательных форме данных и ничего не делать с ними десериализацией) является особенностью 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(); 
    } 
} 

, то вы получите <AppPool xsi:nil="true" /> в XML и ожидаемой десериализации.

+0

если я это сделать, все мои звонки и ссылки на собственность в настоящее время есть проблемы ... 'System.Nullable не содержит определение имени , для Clone(), для ... всех свойств, которые я когда-либо называл «... есть ли способ обойти это? в противном случае я должен был бы прибегнуть к каждой отдельной ссылке или вызову, который я когда-либо делал в своем коде ... что ... LOT ... – MaxOvrdrv

+0

Отредактировал мой ответ. – cyberj0g

+0

То, что я искал. Спасибо! :-) – MaxOvrdrv

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...   
    } 
} 
1

вас ожидания неправы. XmlSerializer будет строить объект (путем вызова безпараметрического конструктора, если его нет - выбрано исключение). Затем свойства будут заполняться один за другим с использованием некоторой магии отражения.

Так что же происходит:

  1. Конструктор вызывается, в котором вы установите значения AppPool и Site.

  2. Site Недвижимость в xml, десериализирована и назначена.

  3. Но нет AppPool в xml, поэтому ничего не меняется и его значение остается (не null).

Чтобы null для AppPool вы не должны установить его значение в конструкторе. Тогда он останется таким, если отсутствует в xml.

Вот один из возможных решений:

public class Deployment 
{ 
    public AppPoolSettings AppPool { get; set; } 
    public WebSiteSettings Site { get; set; } 

    // used by deserializer 
    public Deployment() { } 

    // use this to construct object 
    public static Deployment Create() 
    { 
     return new Deployment() 
     { 
      AppPool = new AppPoolSettings(), 
      Site = new WebSiteSettings() 
     }; 
    } 
} 
Смежные вопросы