ViewState Coherency

I ran into an interesting issue with the new data binding model in ASP.NET 2.0 that I thought I'd document here.

The issue is with the implicit data-bind that occurs between controls like the GridView and their associated declarative data source (like the SqlDataSource). It is now up to the control to perform data binding at the right time, and your job is to just point it to the data source control it should use when it needs to bind data. The data binding itself usually occurs within the EnsureDataBound() method of the control, called within the CreateChildControls() virtual override. Now, if the control has ViewState enabled (which it will by default), the data it binds to in the initial GET request will be cached in ViewState on a subsequent post-back request. In fact, you have probably written code that looks something like this:

    protected void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack)
      {
        myGrid.DataSource = GetDs();
        myGrid.DataBind();
      }
    }

Knowing that the state is being restored from ViewState can save you an additional round-trip to your data store. The controls in ASP.NET 2.0 make this same optimization, so that they will not bother re-binding to the data source if the data is present in ViewState. Now this is usually what you want, but you should be aware of it since it can lead to surprising behavior. For example, if you have a button or other post-back generating control on a form alongside a GridView, and the effect of the button is to modify the underlying database (say it adds a new row to the table being displayed by the GridView), you won't see the changes made to the database when the page is rendered because the GridView is drawing its state from ViewState and not going back to the database. The solution, of course, is to disable ViewState on the GridView and force it to re-retrieve the data with each request.


Posted Jul 20 2005, 01:20 AM by fritz-onion
Filed under:

Comments

Dino Esposito wrote re: ViewState Coherency
on 07-20-2005 1:33 AM
Hi Fritz,
you're probably aware of that, but in alternative to disabling the viewstate, you can also add the following

grid1.DataSourceID = grid.DataSourceID;

to the click handler of the button or whatever it is. No matter what you assign to DataSourceID, setting the property fires the OnPropertyDataChanged event (behavior defined on the BaseDataBoundControl class) which in turns sets RequiresDataBinding=true.
As a result, the control refreshes correctly.

I wonder if it is desirable a behavior (from data-bound controls) that, if enabled, checks for all event handlers in all IButtonControl in the page and automatically refreshes. What do you think?

Cosmin Cristea wrote re: ViewState Coherency
on 07-20-2005 5:06 AM
But, there is an other downfall for this issue. Binding a source to a DataSet and putting it into the ViewState, would be a very bad idea on large data sets, though u will have the data in your page, and also the data in your viewstate, plus the structure information of the dataset, and your page will almost triple its size.
Sergio Pereira wrote re: ViewState Coherency
on 07-20-2005 5:41 AM
Cosmin, what Fritz is calling "data in the voewstate" is only the information needed to restore the control's appearence after the postback, just like it happens today in v1.x. I was aware of Dino's alternative, but I still think it is not intuitive (and maybe not a very good design) to rely on property accessor behaviors to perform such a common tasks. I haven't explored the new databinding model enough to find out if there's a method whos purpose is to cause the control to re-bind to the data. Sometring like..er... ReBind() ? That would be more natural for me. I'm not sure I'd agree with the suggestion of refreshing on every button click, though.
Brock Allen wrote re: ViewState Coherency
on 07-20-2005 6:20 AM
Indeed this is a common problem. Yet one more approach is to simply call DataBind on your GridView from your button click after you've updated the DB.
GuyIncognito wrote re: ViewState Coherency
on 07-20-2005 8:00 AM
Just say NO to ViewState! ControlState (which yeah I know --- uses ViewState) is a much better idea IMHO.

I think it's absurd that someone would think caching the data from a DataGrid or GridView on the client, and having it POSTed back for each request, is a good idea...
Keith Brown wrote re: ViewState Coherency
on 07-20-2005 4:12 PM
Heh, yep Guy. I remember my first run-in with viewstate, years ago. I couldn't figure out why this form with a datagrid took sooooo long to download when I was testing it at home on my DSL connection.

Turns out it wasn't the *download* that was slow, it was the upload of all that viewstate over my slow DSL connection (ISPs throttle outgoing bandwidth to discourage you from running a web server off your DSL line).

I couldn't agree more - posting the data back every time seems wasteful to me. Use server-side data caching if you want to reduce r/t to the database.

But hell, what do I know, I'm just a plumbing weenie anyway :-)
Fritz Onion wrote re: ViewState Coherency
on 07-20-2005 10:13 PM
Dino - I hadn't seen that solution, interesting but 'hacky' :) I don't think trying to solve the problem by checking for any events is really a good idea, it's better that people just be aware of the issue and plan accordingly. I honestly wish they had left ViewState disabled by default for GridView/DetailsView since they tend to be so large - since you can cache the data sources now, there's an equally simple solution to avoiding RTs to the DB.
Dino Esposito wrote re: ViewState Coherency
on 07-21-2005 12:03 AM
Fritz, I agree of course.
I was going to reply here. Then I thought a post of mine to comment is fine as well :-)

http://weblogs.asp.net/despos/archive/2005/07/21/420089.aspx
Christopher Steen - Learning .NET wrote Link Listing - July 21, 2005
on 07-21-2005 8:08 PM

(Amazing) Code Smell - GC.Collect()
BizTalk 2006 Beta Released
Continuous Integration for Visual...
Johan Danforth wrote re: ViewState Coherency
on 08-21-2005 11:44 PM
Ah, thanks Fritz, that explains why my master/details view didn't behave as I thought it would! Arghh.... 2 hours down the drain :)

Thanks!
.net_2.0 wrote Using IFrames and GridView...Mac ViewState Again...
on 12-14-2005 2:42 AM
With my Sites-Easy project (Cavalia) - I was re-writing the Admin portion of the original CSK. ...

Add a Comment

(required)  
(optional)
(required)  
Remember Me?