从 WebControl 序列化中省略属性

发布于 2024-09-05 14:48:56 字数 3238 浏览 5 评论 0原文

我必须序列化从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

贪了杯 2024-09-12 14:48:56

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

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

XXXSpecified has to be a property, not a method :

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

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 a XXXSpecified property


EDIT:

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 :

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文