Wednesday, October 04, 2006

Concurrency problem with auto-binding GridView

I always was suspicious about using ObjectDataSource as data source for ASP.NET 2.0 controls. It saves you some C# (or VB.NET) coding, but adds lots of automatically generated ASPX stuff, which is hard to maintain. Plus flexibility of the code is just not there.

Now I have another good reason not to use ObjectDataSource and automatic binding, because such approach has serious concurrency issues.
Basically if two users are using the same page simultaneously, they could delete rows which they didn’t intend to delete.

This ugly bug caused by the fact that datagrid is trying to delete rows based on row index, not based on row ID.
Read more details about the issue in: Concurrency issues with GridView by jdcrutchley.

Scott Mitchell provides a workaround (hack) to this problem, so you still can use ObjectDataSource. However the need of using hacks just kills the whole idea of using ObjecDataSource with automatic GridView binding. The advantage was to make coding easier. Now the coding with ObjecDataSource is getting more complex than straitforward approach which I like to use:
============
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="false">
  <Columns>
    <asp:TemplateField HeaderText="Delete">
      <ItemTemplate>
        <asp:LinkButton ID="Delete" runat="server" Text="Delete" OnCommand=" Delete_Command" CommandArgument='<%# Eval("RowId") /%>' />
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>


protected void Page_PreRender(object sender, EventArgs e)
{
  gridView.DataSource = MyBusinessClass.GetMyData();
  gridView.DataBind;
}

protected void Delete_Command(object sender, CommandEventArgs e)
{
  int rowId = int.Parse(e.CommandArgument);
  MyBusinessClass.DeleteRow(rowId);
}
============

2 comments:

Scott said...

Please keep in mind that this only occurs if ViewState is disabled. If you leave ViewState on the GridView enabled, then this concurrency concern is a non-issue.

Anonymous said...

Be sure that you don't have a container control (PlaceHolder) with EnableViewState=False, nullifying EnableViewState=True on the gridview say in a user control.

We still had the concurrency issue even after enabling viewstate on the gridview because viewstate was disabled on the PlaceHolder control in the main web form that included the user control that contains the gridview.

Followers

About Me

My Photo
Email me: blogger at dennisgorelik.com