in

ASP.NET Weblogs

Casey Roach

Problems with GridView and a Database persisted Viewstate

 

I'm currently working on a project that requires a lot of controls to be displayed on a single page, with a lot of user input.  This means I'm using a few UpdatePanels wrapped around this content.  Most of the controls are user editable, similar to a data entry screen.  What this also means is a large Viewstate field being posted back to my server each time I update any of the content.

Among this content, are a few GridViews I've been working with.  One in particular recently broke after I changed a few things on the page.  In particular, I was no longer able to update a row.  I used to be able to (and it worked beautifully), but no longer.  Take a look at the following code:

   88 <asp:GridView ID="CodeGrid" runat="server" CssClass="Codes" AutoGenerateColumns="False"

   89     OnRowCommand="CodeGrid_RowCommand" DataSourceID="SqlDataSource1" ShowFooter="True"

   90     DataKeyNames="PK" OnRowUpdating="CodeGrid_RowUpdating" EnableViewState="false">

   91     <Columns>

   92         <asp:TemplateField HeaderText="PK" Visible="false">

   93             <ItemTemplate>

   94                 <%# Eval("PK") %>

   95             </ItemTemplate>

   96         </asp:TemplateField>

   97         <asp:TemplateField HeaderText="Code Section">

   98             <ItemTemplate>

   99                 <%# Eval("CodeSection") %>

  100             </ItemTemplate>

  101             <EditItemTemplate>

  102                 <asp:TextBox ID="EditCodeSection" CssClass="CodeTextBox" runat="server" MaxLength="12"

  103                     Text='<%# Bind("CodeSection") %>' />

  104             </EditItemTemplate>

  105             <FooterTemplate>

  106                 <asp:TextBox ID="InsertCodeSection" CssClass="CodeTextBox" runat="server" MaxLength="12"

  107                     Text='<%# Bind("CodeSection") %>' />

  108             </FooterTemplate>

  109         </asp:TemplateField>

  110         <asp:TemplateField HeaderText="Offense Code">

  111             <ItemTemplate>

  112                 <%# Eval("OffenseCode") %>

  113             </ItemTemplate>

  114             <EditItemTemplate>

  115                 <asp:TextBox ID="EditOffenseCode" Width="95%" CssClass="CodeTextBox" runat="server"

  116                     MaxLength="6" Text='<%# Bind("OffenseCode") %>' />

  117             </EditItemTemplate>

  118             <FooterTemplate>

  119                 <asp:TextBox ID="InsertOffenseCode" Width="95%" CssClass="CodeTextBox" runat="server"

  120                     MaxLength="6" Text='<%# Bind("OffenseCode") %>' />

  121             </FooterTemplate>

  122         </asp:TemplateField>

  123         <asp:TemplateField HeaderText="Description">

  124             <ItemTemplate>

  125                 <%# Eval("Description") %>

  126             </ItemTemplate>

  127         </asp:TemplateField>

  128         <asp:TemplateField HeaderText="Counts">

  129             <ItemTemplate>

  130                 <%# DisplayCounts( Eval("Counts","{0:d}"))%>

  131             </ItemTemplate>

  132             <EditItemTemplate>

  133                 <asp:TextBox ID="EditCounts" Width="90%" CssClass="CodeTextBox" runat="server" MaxLength="2"

  134                     Text='<%# Bind("Counts") %>' />

  135             </EditItemTemplate>

  136             <FooterTemplate>

  137                 <asp:TextBox ID="InsertCounts" Width="90%" CssClass="CodeTextBox" runat="server"

  138                     MaxLength="2" Text='<%# Bind("Counts") %>' />

  139             </FooterTemplate>

  140         </asp:TemplateField>

  141         <asp:TemplateField>

  142             <ItemStyle CssClass="GridButton" />

  143             <ItemTemplate>

  144                 <asp:Button CssClass="GridButtons" runat="server" ID="Edit" Text="Edit" CommandName="Edit" />

  145                 <asp:Button CssClass="GridButtons" runat="server" ID="Delete" Text="Delete" CommandName="Delete" />

  146             </ItemTemplate>

  147             <EditItemTemplate>

  148                 <asp:Button CssClass="GridButtons" runat="server" ID="Update" Text="Save" CommandName="Save" />

  149                 <asp:Button CssClass="GridButtons" runat="server" ID="Cancel" Text="Cancel" CommandName="Cancel" />

  150             </EditItemTemplate>

  151             <FooterTemplate>

  152                 <div style="text-align: center;">

  153                     <asp:Button CssClass="GridButtons" runat="server" ID="Insert" Text="Add" CommandName="InsertNew" />

  154                     <asp:Button CssClass="GridButtons" runat="server" ID="Cancel" Text="Cancel" CommandName="CancelNew" />

  155                 </div>

  156             </FooterTemplate>

  157         </asp:TemplateField>

  158     </Columns>

  159     <EmptyDataRowStyle CssClass="EmptyCodeRow" />

  160     <RowStyle CssClass="CodeRow" />

  161     <EditRowStyle CssClass="EditCodeRow" />

  162     <SelectedRowStyle CssClass="SelectedCodeRow" />

  163     <HeaderStyle CssClass="CodeHeader" />

  164     <AlternatingRowStyle CssClass="AltCodeRow" />

  165     <EmptyDataTemplate>

  166         Code Section:<asp:TextBox CssClass="CodeTextBox" runat="server" ID="NoDataCodeSection"

  167             Width="20%" />

  168         Offense:<asp:TextBox CssClass="CodeTextBox" runat="server" ID="NoDataOffenseCode"

  169             Width="15%" />

  170         Counts:<asp:TextBox CssClass="CodeTextBox" runat="server" ID="NoDataCounts" Width="10%" />

  171         &nbsp;&nbsp;&nbsp;<asp:Button CssClass="GridButtons" runat="server" ID="NoDataInsert"

  172             CommandName="NoDataInsert" Text="Add" />

  173     </EmptyDataTemplate>

  174 </asp:GridView>

 

Ok, so it’s a lot of code, but I feel you should see the entire thing to get an idea of what I’m working with.  The SqlDataSource I’m referencing as the Data source has valid update, select, insert, and delete commands along with the correct parameters.  I changed nothing in the GridView or the SqlDataSource between when it was working and when it broke.

What I did, however is try a different method of persisting the ViewState other than on the page itself.  While looking around, I found a post by Adrian O’Connor where he shows a method of saving/loading the ViewState from SQL server.  I implemented his approach a couple of weeks ago, along with quite a few other changes to the UI.  This week, however, I noticed the OnRowCommand event of the GridView was not firing when I clicked the ‘Save’ button within the EditItemTemplate on line 157.  The ‘Edit’ button fired the event fine, as did the ‘Delete’, but it seemed that whenever there was a change to the initial markup of the GridView, the OnRowCommand event would not fire. 

I spent two days looking for answers, of which multiple Databinding issues were usually the problem.  None of the solutions I found worked for me.  After two days of working on the problem, I discovered that it was the Viewstate change I made that was causing the problem.  I had overridden the PageStatePersister property on the page to use the custom PageStatePersister I created from Adrian’s blog.  After removing this property and letting the ViewState store itself on the page like normal, the OnRowCommand event was not firing for the update command.

I don’t know why this caused the GridView’s natural functioning to break.  The ‘Save’ button was still posting back to the server as I saw it in the Page_Load method, but it was never hitting the OnRowCommand or any Update events either.  I’m guessing that the ViewState was not being updated properly so that the page wasn’t expecting the ‘Save’ button’s click/OnRowCommand event.

Until I find out why this is happening, I’ve removed the custom ViewState Persister, and am going to rely on storing the ViewState on the page.  Maybe someone out there can explain to me why this is happening.

 
Published Jul 09 2008, 10:51 AM by Casey Roach
Filed under: , ,

Comments

 

Mark Hildreth said:

I'm not sure what the problem might be, but if you're just trying to keep the viewstate off the page, you might also want look into the SessionStatePagePersister:

msdn.microsoft.com/.../system.web.ui.sessionpagestatepersister.aspx

I've been using this for a long time and it works great. It doesn't even chew up memory usage on ther server that badly because it only keeps the previous 9 viewstates (pers user obviously) at any given time. As long as you don't hit the back button more than 9 times, you're fine. You can also up the setting in the web.config. Hope that helps!

July 10, 2008 9:25 AM
 

Casey Roach said:

Interesting ... Do you know how this fares in a web farm?

July 10, 2008 6:26 PM

Leave a Comment

(required)  
(optional)
(required)  
Add