问题
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