天天看點

關閉Viewstate

 ​

我的前面一個文章中提到了asp.net如何管理狀态,這裡有一個應用的執行個體。當我們使用很多servercontrol的時候或者servercontrol的資料比較多的時候,有時候我們會發現浏覽器想用戶端送出的資料量大的超出我們的想象,如果你做的事一個小應用無所,如果你做的是關鍵應用,或者公網應用,你就會發現受不了了,如果一個頁面自己送出以下就上百k,折合成網絡傳輸就是1M,那麼你需要多大的帶寬啊。

怎麼辦呢?Asp.net2.0提供了一個enableviewstate的控件屬性,使得我們可以關閉viewstate,減少浏覽器到伺服器的資料傳輸量,那麼,這個東西怎麼樣呢?

看這個例子:   

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!this.IsPostBack) 

        { 

            DropDownList1.Items.Add("dd1"); 

            DropDownList1.Items.Add("dd2"); 

            DropDownList1.SelectedIndex = 0; 

        }

    }

    protected void Button1_Click(object sender, EventArgs e)

        int i = DropDownList1.SelectedIndex; 

        i = DropDownList1.Items.Count;

1。如果enableviewstate=true,顯然是正确的,當button click的時候,IsPostBack=true,不會給DropDownList1再次指派;;Viewstate="/wEPDwUJMjU2NjMzNzY5D2QWAgIDD2QWAgIFDxBkDxYCZgIBFgIQBQNkZDEFA2RkMWcQBQNkZDIFA2RkMmdkZGTtIIu8ebWaFhzv4IWvgZWfL++vYA=="

2。如果enableviewstate=fasle,Viewstate="/wEPDwUKLTU1NjAxNjM5NWRkwyZK+jXFlf1ONOZERfpuPpvR8sg=" 顯然,小了很多。但是,無論使用者如何選擇,DropDownList1.SelectedIndex=-1,而且DropDownList1是空的,是以不對,

3。但是如果将DropDownList1.Items.Add("dd1");DropDownList1.Items.Add("dd2");放到if (!this.IsPostBack)的外面,還是不對,這個時候雖然DropDownList1不空,但是使用者選擇的結果無法傳遞過來viewstate和2相同

4。如果将DropDownList1.Items.Add("dd1");DropDownList1.Items.Add("dd2");取消,然後在設計狀态給DropDownList1賦好值,就對了Viewstate差不多這說明實際上controlstate還是其作用了,雖然沒有viewstate,但是使用者選擇了什麼還是有的,隻不過按照前面的方法去做,在pageload之前,controlstate已經取出來了,可是當時的DropDownList1還沒有指派,是以沒有存進去,這就說明在viewstate關閉的情況下,在page_load裡面給控件指派是有風險的

5。大多數情況下使用者肯定是從資料庫等地方取出東西動态指派給DropDownList1,是以怎麼解決呢?我們找别的事件    protected override void OnInitComplete(EventArgs e)    {        DropDownList1.Items.Add("dd1");        DropDownList1.Items.Add("dd2");    }

msdn:In this stage of the page's life cycle, all declared controls on the page are initialized, but the page's view state is not yet populated. You can access server controls, but they will not yet contain information returned from the user.是以這個狀态下還沒有viewstate,controlstate,是以可以先綁定,綁定完畢後asp。net就會把controlstate給這個控件了

6。是以,關閉了viewstate,雖然關鍵資訊還可以使用,但是很多東西發生了變化,尤其是給控件初始化資料的時機就不一樣了,按照上面的方法雖然可以了,減少了viewstate網絡傳輸的量,但是可以看到,每一次調用,無論是postback還是非postback,都需要重新綁定,如果資料從資料庫來,其實就是加重了資料庫的負擔,是以,是否關閉viewstate實際上是在網絡和資料庫性能上做一個折中選擇。最關鍵的,程式寫法會發生變化。是以,viewstate最适合關閉的場景還是dbgrid之類的隻是顯示用的東西,如果要回傳使用者選擇修改的内容,就比較麻煩了。

7。當然,還有一個做法是,我們可以在用戶端寫腳本,如果使用者選擇了什麼,我們就放到一個hidden元素裡面去,倒是後把這個hidden送出了就是了,但是這樣就失去了server控件的很多優勢了

8。另外,像textbox之類的,就不需要這麼麻煩了,測試表明無論是否禁用viewstate,都沒有什麼變化,我想這是因為,textbox在用戶端就是一個标準的input,他的text是不需要asp.net使用viewstate來處理的,其他的屬性我就沒有嘗試了。但是如果看看checkbox就明白了,如果關閉了它的viewstate,我們是可以取到他的value的,但是服務端動态設定它的text就回不來了。