从WebControl序列化中省略属性

时间:2010-06-14 18:25:36

标签: c# xml-serialization web-controls

我必须序列化从WebControl继承的几个对象以进行数据库存储。这些包括几个不必要的(对我来说)属性,我宁愿从序列化中省略。例如BackColor,BorderColor等

以下是我从WebControl继承的一个控件的XML序列化示例。

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

我一直在尝试为继承自WebControl的控件创建一个公共基类,并使用“xxx Specified”技巧选择性地选择不序列化某些属性。

例如,要忽略空的BorderColor属性,我希望

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

工作,但在序列化过程中从未调用过。

我也在类中尝试过序列化和基类。

由于类本身可能会发生变化,因此我不想创建自定义序列化程序。有什么想法吗?

修改

虽然显然不正确,但我已经在使用XmlAttributeOverrides了。我没有意识到你无法指定基类。我调整了我的例程,但它仍然无法正常工作。以下是我尝试过的一些细节。

我有一个名为Activity的WebControl,它有一个ContainerPanel(继承Panel),它包含几个SerializePanel类型的控件(也继承了Panel)。

尝试1 我将[XmlIgnore]属性添加到SerializePanel的新属性没有任何效果。该属性仍包含在序列化中。

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

尝试2 我也在SerializePanel的声明中尝试了* Specified,但它被忽略了

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

注意:为了能够序列化Control,必须添加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>
...

1 个答案:

答案 0 :(得分:0)

XXXSpecified必须是属性,而不是方法:

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

此外,XmlIgnore属性是不必要的,因为只读属性不是序列化的(无论如何它是代码中的方法)

或者,您可以使用ShouldSerializeXXX 方法代替XXXSpecified属性


编辑:

根据Marc的回答,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);

这种方法可能更好,因为您不需要为控件创建公共基类。此外,您不需要使用除序列化之外没有任何用途的新公共成员污染您的类