从 WebControl 序列化中省略属性
我必须序列化从 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指定" 技巧有选择地选择不序列化某些属性。
例如,要忽略空的 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);
}
注意:为了能够序列化控件,必须向 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>
...
I have to serialize several objects inheriting from WebControl for database storage. These include several unecessary (to me) properties that I would prefer to omit from serialization. For example BackColor, BorderColor, etc.
Here is an example of an XML serialization of one of my controls inheriting from WebControl.
<Control xsi:type="SerializePanel">
<ID>grCont</ID>
<Controls />
<BackColor />
<BorderColor />
<BorderWidth />
<CssClass>grActVid bwText</CssClass>
<ForeColor />
<Height />
<Width />
...
</Control>
I have been trying to create a common base class for my controls that inherits from WebControl and uses the "xxxSpecified" trick to selectively choose not to serialize certain properties.
For example to ignore an empty BorderColor property, I'd expect
[XmlIgnore]
public bool BorderColorSpecified()
{
return !base.BorderColor.IsEmpty;
}
to work, but it's never called during serialization.
I've also tried it in the class to be serialized as well as the base class.
Since the classes themselves might change, I'd prefer not to have to create a custom serializer. Any ideas?
Edit:
I was already using XmlAttributeOverrides
though apparently incorrectly. I didn't realize you couldn't specify a base class. I tweaked my routine, but it is still not working. Here are some more details of the things I've tried.
I have WebControl named Activity, that has a ContainerPanel (inherits Panel) which contains several controls of type SerializePanel (also inherits Panel).
Attempt 1
I added the [XmlIgnore] attributes to new properties of SerializePanel has no effect. The property is still included in serialization.
//This is ignored
[XmlIgnore]
public new System.Drawing.Color BackColor{
get { return base.BackColor; }
set { }}
Attempt 2
I also tried the *Specified in the declaration of SerializePanel, but it was ignored
public bool BackColorSpecified
{
get { return !base.BackColor.IsEmpty; }
}
Attempt 3
Then in the serializer I passed the overrides created here:
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);
}
Note: The attribute additions to the System.Web.UI.Control type are necessary in order to be able to serialize a Control.
The resulting XML snippet is for each attempt was
<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>
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
XXXSpecified
必须是一个属性,而不是一个方法:此外,
XmlIgnore
属性是不必要的,因为只读属性没有序列化(无论如何它是您的方法中的一个方法)代码)或者,您可以使用
ShouldSerializeXXX
方法 而不是XXXSpecified
属性编辑:
根据 Marc 的回答,
XXXSpecified 技巧在这里不起作用...
但是,您还有另一个选择:
XmlAttributeOverrides
类。这允许您自定义序列化,而无需更改类的代码:这种方法可能更好,因为您不需要为控件创建公共基类。此外,您不需要用除了序列化之外没有任何用途的新公共成员来污染您的类
XXXSpecified
has to be a property, not a method :Also, the
XmlIgnore
attribute is unnecessary, since read-only property are not serialized (and anyway it was a method in your code)Alternatively, you can use a
ShouldSerializeXXX
method instead of aXXXSpecified
propertyEDIT:
According to Marc's answer, the
XXXSpecified
trick won't work here...However, there's another option available to you : the
XmlAttributeOverrides
class. This allows you to customize the serialization without changing the code of the class :This approach is probably better, because you don't need to create a common base class for your controls. Also, you don't need to pollute your classes with new public members that serve no purpose except serialization