眾所周知在編寫WebCustomControl時繼承於WebControl基類的Attributes以及其AttributesCssStyle屬性是十分常用和重要的但就是這兩個重要的屬性如果開發中使用不當卻會帶來莫名其妙的效率問題
由於html的靈活性和不完備性導致了WebControl基類沒有完整的表現html元素所提供和支持的所有標簽屬性和CSS屬性(當然由於不同browser的兼容問題要提供完備的屬性是不可能的)又由於很多html標簽屬性和CSS屬性都是很生僻的很少或極少被使用如果要完備的支持反而會成為WebControl的負擔所以Attributes和AttributesCssStyle這兩個屬性很好的解決了這個問題當然這兩個屬性除了支持應有的html標簽屬性和CSS屬性外還支持任何合法的自定義key/value對這裡要討論的問題就來之這個對自定義key/value對的支持上
Attributes屬性的類型是一個AttributeCollection本來很自然的一個東西可是不知道怎麼搞得AttributeCollection的構造函數卻需要一個StateBag參數
public AttributeCollection(StateBag bag)
{
this_bag = bag;
}
這樣的結果就是Attributes和AttributesCssStyle可能會被保存在ViewState中事實上ASPNET默認確實會保存其中的內容到ViewState中
這種設計真的是讓人覺得莫名其妙在大家對ViewState效率問題的討論中覺得ViewState確實是雞肋用來保持一些服務器狀態和數據讓大家覺得方便也就算了可是居然把和UI相關的內容都一股腦存到ViewState裡真的是瘋狂
下面是使用Attributes定義了一些自定義內容後的ViewState的情形
// AnalysisReport自定義控件上定義了一些自定的內容
Attributes和AttributesCssStyle被自動保存到ViewState中後除了ViewState體積急增後PostBack時Load ViewState的負擔也同時增大了上面這個事例中的頁面PostBack的LoadState代價如下圖
實際上我在編寫控件時從來沒有想過要保持Attributes和AttributesCssStyle也沒有想過要再次使用其中的數據而且這個默認保存到ViewState的行為居然不能定制(至少我還沒有發現)後來想到在ASPNET頁面生存期中SaveState結束在PreRender中所以在Render事件中使用Attributes和AttributesCssStyle的就不會保存到ViewState中去
修改代碼
protected override void OnPreRender(EventArgs e)
{
thisAttributes[abc] = ;
thisAttributesCssStyle[abcstyle] = style;
baseOnPreRender(e);
} 為如下形式
protected override void Render(HtmlTextWriter output)
{
this
Attributes[
abc
] =
;
this
Attributes
CssStyle[
abc
style
] =
style
;
output
Write(Text);
}
就不會再將Attributes和AttributesCssStyle保存到ViewState中了上面那個AnalysisReport按上面的示例修改後綁定同樣數據的運行效果為
LoadState的代價也大大降低其開銷為
From:http://tw.wingwit.com/Article/program/net/201311/15458.html