2010-06-14 71 views
0

我必須序列化從WebControl繼承的幾個對象以進行數據庫存儲。這些包括幾個不必要的(我)屬性,我寧願從序列化中省略。例如BackColor,BorderColor等。從WebControl序列化忽略屬性

這裏是我的一個控件從WebControl繼承的XML序列化的例子。

<Control xsi:type="SerializePanel"> 
     <ID>grCont</ID> 
     <Controls /> 
     <BackColor /> 
     <BorderColor /> 
     <BorderWidth /> 
     <CssClass>grActVid bwText</CssClass> 
     <ForeColor /> 
     <Height /> 
     <Width /> 
     ... 
     </Control> 

我一直在努力創建我的控制一個共同的基類,從Control繼承和使用「XXX Specified」招選擇性地選擇不序列化的某些屬性。

例如忽略空BorderColor屬性,我期望

[XmlIgnore]  
public bool BorderColorSpecified() 
{ 
    return !base.BorderColor.IsEmpty; 
} 

工作,但它序列化過程中從來沒有叫。

我也試過它在類中被序列化以及基類。

由於類本身可能會改變,所以我不想創建自定義序列化器。有任何想法嗎?

編輯:我已經使用XmlAttributeOverrides但顯然不正確

。我沒有意識到你不能指定一個基類。我調整了我的例程,但它仍然無法正常工作。以下是我嘗試過的一些細節。

我有一個名爲Activity的WebControl,它有一個ContainerPanel(繼承面板),它包含幾個SerializePanel類型的控件(也繼承Panel)。

嘗試1 我將[XmlIgnore]屬性添加到SerializePanel的新屬性沒有任何影響。該屬性仍然包含在序列化中。

//This is ignored 
[XmlIgnore] 
public new System.Drawing.Color BackColor{ 
get { return base.BackColor; } 
set { }} 

嘗試2 我也試過*指定在SerializePanel的聲明,但它忽略

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

回答

0

XXXSpecified必須是一個屬性,而不是方法:

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

此外,XmlIgnore屬性是不必要的,因爲讀的只有屬性沒有序列化(並且無論如何這是您的代碼中的一種方法)

或者,您可以使用ShouldSerializeXXX方法代替XXXSpecified財產


編輯:

根據馬克的回答,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); 

這種方法可能會更好,因爲你並不需要創建一個公共基類的控件。此外,你不需要污染你的班級,除了系列化以外沒有任何用途的新的公共成員

+0

我真的很感謝你的見解。不幸的是,我仍然懷疑存在的問題與我嵌套控件的事實有關,儘管這只是一個預感。我想知道你是否可以借鑑一下還有什麼問題。請參閱問題編輯。 – Laramie 2010-06-14 20:42:42

+0

@Laramie,您需要指定屬性定義的類型的屬性。例如,BackColor在WebControl中定義,而不是在Control中定義。所以你必須寫'overrides.Add(typeof(WebControl),strAttr,ignoreAtrs)' – 2010-06-14 21:03:27

+0

這很有道理。適用於繼承WebControl的所有對象,但我仍然沒有看到有選擇地選擇繼承WebControl的哪些類型應具有其屬性序列化的方法。如果我在SerializePanel這樣的繼承類型上創建** public public System.Drawing.Color BackColor **屬性並設置** overrides.Add(typeof(SerializePanel),「BackColor」,ignoreAtrs)** BackColor仍然是序列化的。 – Laramie 2010-06-14 21:41:13