Omit Properties from WebControl Serialization

我们两清 提交于 2019-12-11 19:46:02

问题


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>
...

回答1:


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



来源:https://stackoverflow.com/questions/3039794/omit-properties-from-webcontrol-serialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!