我必须序列化从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>
...
答案 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);
这种方法可能更好,因为您不需要为控件创建公共基类。此外,您不需要使用除序列化之外没有任何用途的新公共成员污染您的类