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.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +109