Tuesday, 29 January 2008

Binding It Twice

Last week I, like a lot of other Asp.Net newbies, got a weird validation error on my page saying, "Invalid postback or callback argument". The funny thing is, I've got another error two days earlier, even more weird, saying,

Item has already been added. Key in dictionary: 'ID' Key being added: 'ID'

The weird thing about this error is that I was adding an item to a GridView via a regular mechanism, using the prescribed DetailsView and ObjectDataSource, no funky MVP stuff. The "ID" in this error refers to the key column.

What caused the error in both cases was calling the DataBind method on postback, which you shouldn't usually do if you have ViewState enabled. In the second case, I blindly called DataBind on the page itself.

So, the rule for other newbie who happen to read this:
Whenever you init your page, call DataBind for the GridView only if you haven't set the DataSourceID, and always wrap it with "If Not IsPostBack".
If you add/change your record via a DetailsView that is bound to the same DataSource, you don't have to call DataBind on postback, since the DataSource will notify the GridView of the change.
If you add/change your record via some other means, call DataBind after it has been changed.

Here's my stack trace for Google:
[ArgumentException: Item has already been added. Key in dictionary: 'ID'  Key being added: 'ID']
System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) +2904181
System.Collections.Hashtable.Add(Object key, Object value) +11
System.Collections.Specialized.OrderedDictionary.Add(Object key, Object value) +49
System.Web.UI.WebControls.DataKey.LoadViewState(Object state) +88
System.Web.UI.WebControls.DataKey.System.Web.UI.IStateManager.LoadViewState(Object state) +4
System.Web.UI.WebControls.GridView.LoadDataKeysState(Object state) +310
System.Web.UI.WebControls.GridView.LoadControlState(Object savedState) +450
System.Web.UI.Control.LoadControlStateInternal(Object savedStateObj) +118
System.Web.UI.Page.LoadAllState() +212
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +109

1 comment:

Anonymous said...

Many years later I read this blog
First - to my eyes the color scheme is very difficult to read
But this is not the point. I got the same issue and am going to try it. The strange thing is that it doesn't cause it on my local computer when testing
Thanks