2010-06-14 83 views
0

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

这里是我的一个控件从WebControl继承的XML序列化的例子。

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

我一直在努力创建我的控制一个共同的基类,从Control继承和使用“XXX Specified”招选择性地选择不序列化的某些属性。

例如忽略空BorderColor属性,我期望

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

工作,但它序列化过程中从来没有叫。

我也试过它在类中被序列化以及基类。

由于类本身可能会改变,所以我不想创建自定义序列化器。有任何想法吗?

编辑:我已经使用XmlAttributeOverrides但显然不正确

。我没有意识到你不能指定一个基类。我调整了我的例程,但它仍然无法正常工作。以下是我尝试过的一些细节。

我有一个名为Activity的WebControl,它有一个ContainerPanel(继承面板),它包含几个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属性是不必要的,因为读的只有属性没有序列化(并且无论如何这是您的代码中的一种方法)

或者,您可以使用ShouldSerializeXXX方法代替XXXSpecified财产


编辑:

根据马克的回答,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 2010-06-14 20:42:42

+0

@Laramie,您需要指定属性定义的类型的属性。例如,BackColor在WebControl中定义,而不是在Control中定义。所以你必须写'overrides.Add(typeof(WebControl),strAttr,ignoreAtrs)' – 2010-06-14 21:03:27

+0

这很有道理。适用于继承WebControl的所有对象,但我仍然没有看到有选择地选择继承WebControl的哪些类型应具有其属性序列化的方法。如果我在SerializePanel这样的继承类型上创建** public public System.Drawing.Color BackColor **属性并设置** overrides.Add(typeof(SerializePanel),“BackColor”,ignoreAtrs)** BackColor仍然是序列化的。 – Laramie 2010-06-14 21:41:13

相关问题