简体   繁体   English

从WebControl序列化中忽略属性

[英]Omit Properties from WebControl Serialization

I have to serialize several objects inheriting from WebControl for database storage. 我必须序列化从WebControl继承的几个对象以进行数据库存储。 These include several unecessary (to me) properties that I would prefer to omit from serialization. 这些包括一些我不想在序列化中忽略的不必要的属性(对我而言)。 For example BackColor, BorderColor, etc. 例如BackColor,BorderColor等。

Here is an example of an XML serialization of one of my controls inheriting from WebControl. 这是从WebControl继承的我的一个控件的XML序列化示例。

<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 "xxx Specified " trick to selectively choose not to serialize certain properties. 我一直在尝试为控件创建一个通用的基类,该基类继承自WebControl,并使用“ xxx Specified ”技巧来有选择地选择不序列化某些属性。

For example to ignore an empty BorderColor property, I'd expect 例如,忽略一个空的BorderColor属性,我希望

[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. 我已经在使用XmlAttributeOverrides尽管显然是错误的。 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). 我有一个名为Activity的WebControl,它具有一个ContainerPanel(继承面板),其中包含几个SerializePanel类型的控件(也继承了Panel)。

Attempt 1 I added the [XmlIgnore] attributes to new properties of SerializePanel has no effect. 尝试1我将[XmlIgnore]属性添加到SerializePanel的新属性中没有任何作用。 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 尝试2我也尝试了SerializePanel声明中的* Specified,但是被忽略了

public bool BackColorSpecified
    {
        get { return !base.BackColor.IsEmpty; }
    }

Attempt 3 Then in the serializer I passed the overrides created here: 尝试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);
}

Note: The attribute additions to the System.Web.UI.Control type are necessary in order to be able to serialize a Control. 注意:为了能够序列化控件,必须在System.Web.UI.Control类型中添加属性。

The resulting XML snippet is for each attempt was 每次尝试的结果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>
...

XXXSpecified has to be a property, not a method : XXXSpecified必须是属性,而不是方法:

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) 另外, XmlIgnore属性也是不必要的,因为只读属性不会被序列化(无论如何它是您代码中的方法)

Alternatively, you can use a ShouldSerializeXXX method instead of a XXXSpecified property 或者,您可以使用ShouldSerializeXXX 方法而不是XXXSpecified属性


EDIT: 编辑:

According to Marc's answer, the XXXSpecified trick won't work here... 根据Marc的回答, XXXSpecified技巧在这里不起作用...

However, there's another option available to you : the XmlAttributeOverrides class. 但是,还有另一个可用选项: XmlAttributeOverrides类。 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 另外,您不需要使用新的公共成员来污染您的类,这些新成员除了序列化外没有其他用途

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM