Исключить свойства из сериализации WebControl

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

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

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

Я пытался создать общий базовый класс для своих элементов управления, который наследуется от WebControl и использует "xxx Указано", чтобы выборочно отказаться от сериализации определенных свойств.

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

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

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

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

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

Изменить:

Я уже использовал 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>
...

person Laramie    schedule 14.06.2010    source источник


Ответы (1)


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

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

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

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


РЕДАКТИРОВАТЬ:

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

Однако вам доступен и другой вариант: XmlAttributeOverrides < / a> класс. Это позволяет настраивать сериализацию без изменения кода класса:

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);

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

person Thomas Levesque    schedule 14.06.2010
comment
Я очень ценю вашу проницательность. К сожалению, у меня все еще возникают проблемы, которые, как я подозреваю, связаны с тем, что у меня есть вложенные элементы управления, хотя на данный момент это всего лишь догадка. Интересно, не могли бы вы взглянуть на то, что все еще не так. См. Редактирование вопроса. - person Laramie; 15.06.2010
comment
@Laramie, вам необходимо указать атрибут для типа, для которого определено свойство. Например, BackColor определяется в WebControl, а не в Control. Итак, вы должны написать overrides.Add(typeof(WebControl), strAttr, ignoreAtrs) - person Thomas Levesque; 15.06.2010
comment
В этом есть смысл. Отлично работает для всех объектов, наследующих WebControl, но я до сих пор не вижу способа выборочно выбирать, какие типы, наследующие WebControl, должны иметь сериализованные свойства. Если я создам новое общедоступное свойство System.Drawing.Color BackColor для наследуемого типа, такого как SerializePanel, и установлю overrides.Add (typeof (SerializePanel), BackColor, ignoreAtrs) BackColor будет все еще сериализован. - person Laramie; 15.06.2010