I have removed the Gridview databind instruction from the Page_Load() event and only refresh it when required. It solved the problem. I can see why refreshing the values might mess up with the DataKeys, but I still wonder why it works in localhost !
// don't call this sub in the Page_Load() event
private void RefreshGridview()
{
this.SqlDataSource_Contracts.SelectCommand = GetGridviewSql();
this.GridView_Contracts.DataBind();
Label_Gridview.Text = GridView_Contracts.Rows.Count + " contracts in the database";
}