ViewState optimization

9 posts, 0 answers
  1. Martin Roussel
    Martin Roussel avatar
    246 posts
    Member since:
    Jan 2010

    Posted 12 Jul 2012 Link to this post

    Hi everyone,

    Sorry if such question has already been asked, but i cant find a topic that helps me completely.

    First of all, Im using a RadGrid with most of the grid functions (Sorting, Paging, Grouping and Filtering). Im populating my grid with data coming from my database (as a ObservableCollection<Class>) through the page's code-behind, columns are auto-generated (nothing special so far). Note that my grid's EnableViewState="False".

    The first problem i encountered was i had to use the OnNeedDataSource property (which i added), otherwise i was losing my grid data content when using the sorting and such. I then noticed that OnNeedDataSource was always requesting my database so I created a ViewState variable that will contain my collection variable in order to save those database round-trips (for each sorting, page change, etc.). The approach i chose was to only create a ViewState on the first grid function (ex: first time we do a sort). The reason is because most of my users wont do grid functions at all (so for those users, Viewstate wont be used at all). I accomplished this by adding some handlers (OnItemCommand, OnGroupsChanging) that create the ViewState if it doesnt exist already (OnNeedDataSource checks also for it).

    Everything seemed to work as expected until i noticed that one grid function seemed to be failing at random occasion: playing with the expendable/foldable rows (when header(s) are grouped). The only way i could fix this was by adding the EnableViewState="True" to the grid, but now i end up with 2 ViewState per grid...which i dont really like.

    My questions:
    1-Is it normal that I depend on the EnableViewState="True" for expendable/foldable rows (where all other functions work with my "custom" Viewstate?)
    2-Can that second "auto-generated" Viewstate (EnableViewState="True") be used to do the job of the first one? If yes, how can we access it?
    3-Is there a way to force the OnItemCommand and OnGroupsChanging handlers to be fired before OnNeedDataSource? Having this would save me a round-trip.
    4-Do you propose a better way to save the database round-trips?
    5-I was wondering if it is a best practice to manually clear Viewstate variable that we create ourselves (when page quits/redirect)? If yes, any example?
    6-Do you think letting the grid asking the database everytime would be less load on the server than 2 Viewstates?

    Here are snippets of my code i have so far:
    <telerik:RadGrid ID="RadGrid1" runat="server" PageSize="5" Width="75%"
                    AllowSorting="True" AllowFilteringByColumn="True"  AllowMultiRowSelection="True" AllowPaging="True"
                    ShowGroupPanel="True" GridLines="None" AutoGenerateColumns="True" ShowFooter="True"
                    OnItemCommand="testcomm" OnGroupsChanging="testgroup" OnColumnsReorder="testreorder"
                    OnNeedDataSource="RadGrid1_NeedDataSource" 
                    Skin="WebBlue" EnableViewState="True" >
                    
                        <PagerStyle Mode="NextPrevAndNumeric"></PagerStyle>
     
                        <ClientSettings AllowDragToGroup="True" AllowColumnsReorder="True" ReorderColumnsOnClient="True">
                            <Resizing AllowColumnResize="true" />
                        </ClientSettings>
     
                        <GroupingSettings ShowUnGroupButton="true" />
     
                    </telerik:RadGrid

    protected void RadGrid1_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
        {
            ObservableCollection<PersonDTO> col = new ObservableCollection<PersonDTO>();
     
     
            if (ViewState["RadGrid1_DataSource"] != null)
            {
                col = (ObservableCollection<PersonDTO>)ViewState["RadGrid1_DataSource"];
          
            }
            else
            {
     
                col = GridDataSource2();
     
            }
     
            RadGrid1.DataSource = col;
     
        }
     
     private void LoadViewState()
        {
            ObservableCollection<PersonDTO> col = new ObservableCollection<PersonDTO>();
     
            if (ViewState["RadGrid1_DataSource"] == null)
            {
     
                // collection isn't in view state, so we need to load it from scratch.
                if (RadGrid1.DataSource == null)
                {
                    col = GridDataSource2();
                }
                else
                {
                    col = (ObservableCollection<PersonDTO>)RadGrid1.DataSource;
                }
     
                if (col != null)
                {
     
                    ViewState.Add("RadGrid1_DataSource", col);
     
                }
            }
        }
     
        protected void testcomm(object o, Telerik.Web.UI.GridCommandEventArgs e)
        {
            LoadViewState();
        }
     
        protected void testreorder(object o, Telerik.Web.UI.GridColumnsReorderEventArgs e)
        {
            LoadViewState();
        }
     
        protected void testgroup(object o, Telerik.Web.UI.GridGroupsChangingEventArgs e)
        {
            LoadViewState();
        }


    Thanks...and sorry btw for the long post but i wanted to make everything clear.
  2. Andrey
    Admin
    Andrey avatar
    836 posts

    Posted 17 Jul 2012 Link to this post

    Hi,

    Thank you for contacting us.

    As this help topic says when you are using advanced features of RadGrid like paging, sorting, grouping and filtering you need to use either declarative datasource or NeedDataSource event.

    Additionally, the same features require the EnableViewState property is set to True. This is mentioned in this help topic.

    On the other hand you could not handle the ViewState manually because RadGrid stores many property values in ViewState that are not exposed as public member. Therefore you need handle the ViewState manually.

    You could not change the life-cycle of the control, so you could not force RadGrid to fire ItemCommand and OnGroupsChanging events at different stage.

    I hope this information helps. Let me know if I can assist you any further.

    Kind regards,
    Andrey
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  3. Martin Roussel
    Martin Roussel avatar
    246 posts
    Member since:
    Jan 2010

    Posted 17 Jul 2012 Link to this post

    thanks for the reply. Can you please precise more this part, since it sounds contradictory:

    "On the other hand you could NOT handle the ViewState manually because RadGrid stores many property values in ViewState that are not exposed as public member. Therefore you need handle the ViewState manually."

    To sum it up, can you (or anyone) help answering the questions ive asked, i think some left unanswered:

    My questions:
    1-Is it normal that I depend on the EnableViewState="True" for expendable/foldable rows (where all other functions work with my "custom" Viewstate?) ->YES
    2-Can that second "auto-generated" Viewstate (EnableViewState="True") be used to do the job of the first one? If yes, how can we access it from code-behind? ->?
    3-Is there a way to force the OnItemCommand and OnGroupsChanging handlers to be fired before OnNeedDataSource? Having this would save me a round-trip. -> NO
    4-Do you propose a better way to save the database round-trips? ->?
    5-I was wondering if it is a best practice to manually clear Viewstate variable that we create ourselves (when page quits/redirect)? If yes, any example? ->?
    6-Do you think letting the grid asking the database everytime would be less load on the server than 2 Viewstates? ->?

    TIA
  4. Andrey
    Admin
    Andrey avatar
    836 posts

    Posted 18 Jul 2012 Link to this post

    Hello,

    Please, excuse me fore being unclear.

    I meant "You should not handle ViewState manually."

    I think we are not on the same wave length. When you are doing grouping you should enable the ViewState of RadGrid with the EnableViewState property set to True.

    On the other hand you could store your data in a ViewState property but this property should no be filled conditionally. It should be filled before RadGrid needs the data for example in the PageLoad event. Once you have filled the data container and have the EnableViewState property set to true RadGrid will bind correctly and all the available functionality will work as expected.

    I hope this answers your questions.

    Regards,
    Andrey
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  5. Martin Roussel
    Martin Roussel avatar
    246 posts
    Member since:
    Jan 2010

    Posted 18 Jul 2012 Link to this post

    Andrey,

    Sorry if im not clear, but it doesnt answer my question(s).

    Im using EnableViewState =True and dont plan to change that. I assume, by declaring such thing, the control creates automatically a Viewstate (with an unknown ID??). I dont want neither to use my additional "custom" Viewstate to replace that Viewstate's job, but asking the inverse: Can I access (read) the auto-generated Viewstate (created with the EnableViewState =True) and use that one for my own other purposes (in this case, saving my database round-trip)? The question is basically, what could be the ID of that auto Viewstate? Maybe the answer is no, we cant access it, dont bother... but im asking.

    Basically, what i want to achieve at the end of the day is eliminating completely my "custom" Viewstate and only use the auto-generated one (while having the database round-trip reduced).

    TIA
  6. Andrey
    Admin
    Andrey avatar
    836 posts

    Posted 18 Jul 2012 Link to this post

    Hi,

    ASP.NET ViewState is a client-state persister based on key-value dictionary that is used to save the values of the properties of given control. Doing so you are preserving the client-state of the controls between the postbacks. This ViewState is different for every logged user.

    Since the ViewState is a key-value dictionary the only "ID" that it has is the "ViewState". You are accessing the value of some property by providing the property name through indexers:

    var datasource = ViewState["datasource"];

    You could find more information about the ASP.NET ViewState in this MSDN thread.

    All the best,
    Andrey
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  7. Mick
    Mick avatar
    16 posts
    Member since:
    May 2012

    Posted 29 Jul 2015 Link to this post

    Interesting thread.  A little disappointing though it seems this guy had no luck getting a resolution on this. Telerik radgrid on a page we're serving up is sucking up 90K of viewstate.  I don't quite understand why the only options are on or off for viewstate.  Surely there's an inbetween.... Like having viewstate options for each feature like 

    EnableViewStateSortexpressions
    EnableViewStateFilters

    etc

    etc

  8. Mick
    Mick avatar
    16 posts
    Member since:
    May 2012

    Posted 29 Jul 2015 in reply to Mick Link to this post

    Also the sample supplied here...

    http://www.telerik.com/support/code-library/retain-expanded-selected-state-in-hierarchy-on-rebind

    ...is a nice starter, but inadequate , it should be expanded to include saving of Filters, Sorting, Pagindex etc.
  9. Angel Petrov
    Admin
    Angel Petrov avatar
    1085 posts

    Posted 03 Aug 2015 Link to this post

    Hi,

    Can you please elaborate on the exact functionality you are targeting? Maybe we can provide a possible solution for it.

    As for persisting the grid state there is a built-in solution to the problem and that is using our persistence framework. A demo illustrating such functionality can be seen here.

    Regards,
    Angel Petrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top