State management in ASP.NET MVC and Syncfusion MVC controls

State management in ASP.NET MVC is an interesting throwback to the core concept of statelessness in HTTP—wherein there is no default support for state persistence. Compare this to ASP.NET Web Forms, which by default used ViewState to store the state for each control.

There are many benefits associated with stateless pages, or when state is maintained only on the client browser, via a cookie for example:

· Sites can easily scale to a cluster of servers in a server farm without having to worry about maintaining session state.

· Debugging problems produced by session expiry will not be an issue.

· Cached pages can be put to better use, as most of the page content might stay the same in the absence of session state.

· A session is easy to recover if the server crashes when state is persisted on the client rather than the server.

The MVC team clearly had the above in mind when creating a default, stateless architecture.

Though there is no default support for state persistence in MVC, developers can use several options to enable state persistence across page post-backs:

· Session state.

· ASP.NET cache.

· Cookies.

Each of the above has its own pros and cons, depending on the scale of the deployment. By letting developers build their own persistence logic, ASP.NET MVC encourages developers to follow best practices in ensuring minimalist memory and bandwidth usage, which has been sorely lacking in Web Forms, considering the common abuse of ViewState with caching large, unnecessary information.

State Persistence in Syncfusion Controls

Syncfusion ASP.NET MVC controls adhere to these principles and are stateless by default. However, as a control becomes more complex, like a tree or a grid, it becomes interactive; there is always a necessity to maintain the current visual state of the control somewhere. We facilitate this by including APIs in JavaScript that allow you to retrieve and apply the state of the controls from and into the cookies.

State Persistence in Syncfusion MVC Grid

State persistence in the Grid control can be maintained by using JQuery cookies. This is achieved by saving the expand-and-collapse state of each page in the cookies and rendering the Grid control with reloaded cookies. Here is the code snippet that does this:

var pagingInformation = $.cookie('PagingInfo'); // Define the variable using cookies. Using this variable, store the expand-and-collapse state information of each page.  
pagingInformation = [];
var count = 0;
var indValue;
function ActionBegin(sender, args) {
    // The expand-and-collapse state information is saved when switching over to another page.
    if (args.requestType != "Refresh") {    // To avoid adding pagingInformation while the grid refreshes.
        var element = $find("EntityGrid");
        if ($("#EntityGrid").find(".RecordPlusCollapse").length > 0) {
            var collapsedRows = $("#EntityGrid").find(".RecordPlusCollapse"); // Find all the collapsed state td’s of the current page.
            var indexValue = [];
            $.each(collapsedRows, function (index, rows) {
                indexValue.push($(rows).parent("tr").index())  // Find the parent of the collapsed state (td) and store the parent (tr) index into the array.
            });
            // Get the previous page number from this command.
            var pageNo = element._pager._prevPageNo;
            // If the pagingInformation length is greater than zero.
            if (pagingInformation.length > 0) {
                // This loop is used to check whether the corresponding page information is already stored in the cookies variable.                    
                $.each(pagingInformation, function (index, item) {
                    if (pagingInformation[index][0].PageNo == pageNo) {
                        count = 1;
                        indValue = index;
                    }
                });
                // If the previous page information already exists, then simply replace the current collapsed state details.
                if (count == 1)
                    pagingInformation[indValue][0].CollapsedRowIndex = indexValue;
                    // If the previous page information does not already exist, then simply add PageNo and collapsed state details into the cookies variable.
                else
                    pagingInformation.push([{ "PageNo": pageNo, "CollapsedRowIndex": indexValue }]);
            }
                // Initially, pagingInformation is empty, so we can add PageNo and the corresponding collapsed state row (tr) index value in the cookies variable. 
            else {
                pagingInformation.push([{ "PageNo": pageNo, "CollapsedRowIndex": indexValue }]);
            }
        }
        count = 0;
        //  this JSON.stringify is used to serialize the array.
        $.cookie('PagingInfo', JSON.stringify(pagingInformation));
    }
}
function ActionComplete(sender, args) {
    // Applying the saved state on the grid.
    //Maintained the state while paging and grid refresh.
    //If we click Next Page or refresh the page, then this function is executed.
    if (args.RequestType == "paging" || args.RequestType == "Refresh") {
        var element = $find("EntityGrid");
        // Get currentPageNo from this command.
        var currpageNo = element._pager._currentPageNo;

        // De-serialize the cookies variable data by using the $.parseJSON() command.
        var currentPagingInformation = $.parseJSON($.cookie('PagingInfo'));
        if (currentPagingInformation != null) {
            $.each(currentPagingInformation, function (index, item) {
                if (item[0].PageNo == currpageNo) {
                    $.each(item[0].CollapsedRowIndex, function (ind, i) {
                        // Get the corresponding page information details from the cookies variable and assign it to statePersistenceExpandCollapse. Then, the page is rendered with the expanded-and-collapsed state.
                        $find("EntityGrid").statePersistenceExpandCollapse(i);
                    });
                }
            });
        }
    }
}
Graham High

Graham High is a senior content producer for Syncfusion.