2010-06-14 3 views
0

Мне нужно сериализовать несколько объектов, наследующих WebControl для хранения базы данных. К ним относятся несколько ненужных (для меня) свойств, которые я предпочел бы опустить из сериализации. Например, BackColor, BorderColor и т. Д.Опустить свойства из WebControl Сериализация

Ниже приведен пример сериализации XML одного из моих элементов управления, наследуемых от WebControl.

<Control xsi:type="SerializePanel"> 
     <ID>grCont</ID> 
     <Controls /> 
     <BackColor /> 
     <BorderColor /> 
     <BorderWidth /> 
     <CssClass>grActVid bwText</CssClass> 
     <ForeColor /> 
     <Height /> 
     <Width /> 
     ... 
     </Control> 

Я пытался создать общий базовый класс для моего управления, который наследуется от WebControl и использует «ххх Specified» трюк, чтобы избирательно выбирать не сериализовать определенные свойства.

Например, чтобы игнорировать пустое свойство BorderColor, я бы ожидать

[XmlIgnore]  
public bool BorderColorSpecified() 
{ 
    return !base.BorderColor.IsEmpty; 
} 

работать, но это никогда не вызывается во время сериализации.

Я также пробовал его в классе, который будет сериализован, а также базовом классе.

Поскольку сами классы могут меняться, я бы предпочел не создавать собственный сериализатор. Есть идеи?

Edit:

Я уже использовал XmlAttributeOverrides, хотя, по-видимому неправильно. Я не понимал, что вы не можете указать базовый класс. Я настраивал свою рутину, но она все еще не работает. Вот еще некоторые подробности того, что я пробовал.

У меня есть WebControl с именем Activity, у которого есть ContainerPanel (наследует Panel), который содержит несколько элементов управления типа SerializePanel (также наследует Panel).

Попытка 1 Я добавил [XmlIgnore] атрибуты к новым свойствам SerializePanel не имеет никакого эффекта. Свойство все еще включено в сериализацию.

//This is ignored 
[XmlIgnore] 
public new System.Drawing.Color BackColor{ 
get { return base.BackColor; } 
set { }} 

Покушение 2 Я также попытался * указано в объявлении SerializePanel, но был проигнорирован

public bool BackColorSpecified 
    { 
     get { return !base.BackColor.IsEmpty; } 
    } 

Покушение 3 Тогда в сериализатором я прошел переопределение созданные здесь :

XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 

string[] serPAnelProps = { "BackColor", "BorderColor", "ForeColor", "Site", "Page", "Parent", "TemplateControl", "AppRelativeTemplateSourceDirectory" }; 
foreach (string strAttr in serPAnelProps) 
{ 
    XmlAttributes ignoreAtrs = new XmlAttributes(); 
    ignoreAtrs.XmlIgnore = true; 
    overrides.Add(typeof(SerializePanel), strAttr, ignoreAtrs); 
} 

string[] ignoreProps = { "Site", "Page", "Parent", "TemplateControl", "AppRelativeTemplateSourceDirectory" }; 
foreach (string strAttr in ignoreProps) 
{ 
    XmlAttributes ignoreAtrs = new XmlAttributes(); 
    ignoreAtrs.XmlIgnore = true; 
    overrides.Add(typeof(System.Web.UI.Control), strAttr, ignoreAtrs); 
} 

Примечание. Для возможности сериализации элемента управления необходимо добавить атрибуты к типу System.Web.UI.Control.

Полученный XML фрагмент кода для каждой попытки был

<Activity....> 
... 
<ContainerPanel> 
     <ID>actPnl_grAct207_0</ID> 
    - <Controls> 
    - <Control xsi:type="SerializePanel"> 
     <ID>grCont</ID> 
     <Controls /> 
     <BackColor /> 
     <BorderColor /> 
     <BorderWidth /> 
     <CssClass>grActVid</CssClass> 
     <ForeColor /> 
     <Height /> 
     <Width /> 
     <WidthUnitType>Pixel</WidthUnitType> 
     <HeightUnitType>Pixel</HeightUnitType> 
     <WidthUnit>0</WidthUnit> 
     <HeightUnit>0</HeightUnit> 
     </Control> 
... 

ответ

0

XXXSpecified должно быть свойство, а не метод:

public bool BorderColorSpecified 
{ 
    get { return !base.BorderColor.IsEmpty; } 
} 

Кроме того, атрибут XmlIgnore не является необходимым, так как Read- только свойство не сериализовано (и в любом случае это был метод в вашем коде)

В качестве альтернативы вы можете использовать ShouldSerializeXXXметод вместо XXXSpecified свойство


EDIT:

Согласно ответу Марка,, то XXXSpecified трюк не будет работать здесь ...

Однако, есть еще один вариант для вас : класс XmlAttributeOverrides. Это позволяет настроить сериализацию без изменения кода класса:

XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 

// Ignore the BackColor property 
XmlAttributes attributesBackColor = new XmlAttributes(); 
attributesBackColor.XmlIgnore = true; 
overrides.Add(typeof(WebControl), "BackColor", attributesBackColor); 

// do the same for other properties to ignore... 

XmlSerializer xs = new XmlSerializer(typeof(YourControl), overrides); 

Этот подход, вероятно, лучше, потому что вам не нужно, чтобы создать общий базовый класс для элементов управления. Кроме того, вам не нужно загрязнять ваши классы новыми публичными членами, которые не имеют никакой цели, кроме сериализации.

+0

Я очень ценю ваши идеи. К сожалению, у меня все еще есть проблемы, которые, как я подозреваю, связаны с тем, что у меня есть вложенные элементы управления, хотя на этот раз это просто догадка. Интересно, можете ли вы присмотреть за тем, что еще не так. См. Редактирование вопроса. – Laramie

+0

@Laramie, вам нужно указать атрибут для типа, на котором определено свойство. Например, BackColor определяется в WebControl, а не в Control. Поэтому вы должны написать 'overrides.Add (typeof (WebControl), strAttr, ignoreAtrs)' –

+0

Это имеет смысл. Работает отлично для всех объектов, наследующих WebControl, но я до сих пор не вижу способа выборочного выбора, какие типы, которые наследуют WebControl, должны иметь свои свойства, сериализованные. Если я создаю ** общедоступное новое свойство System.Drawing.Color BackColor ** для типа наследования типа SerializePanel и устанавливаю ** overrides.Add (typeof (SerializePanel), «BackColor», ignoreAtrs) ** BackColor по-прежнему сериализуется. – Laramie

Смежные вопросы