Maintain filters on post

Nov 5, 2013 at 10:59 AM
Hello,
I have used the Grid and everything was great up to the point I added a details button on the grid.
When I filter the grid after I click details all the filtering information is lost.
How can I restore the filters?

thanks
Coordinator
Nov 6, 2013 at 2:29 AM
Hi

Unfortunately, there is no out of box solution for that, because grid uses query string to store filter and sorting settings.
To implement behavour like you want - grid must store all settings in persistent (between other pages) storage, like cookie files.

Another way is to save current filter settings in the session, and use that on another page to build special url that redirect user to grid page with saved settings. like:
        // page with the grid
        public ActionResult Index()
        {
            var repository = new OrdersRepository();
            ViewBag.ActiveMenuTitle = "Demo";
            var grid = new OrdersGrid(repository.GetAll());

            Session["grid-filters"] = grid.Settings.FilterSettings;//store grid filters in the session

            return View(grid);
        }

        //Pages redirect to page with saved filter settings
        public ActionResult Redirect()
        {
            var filterSettings = Session["grid-filters"] as IGridFilterSettings;
            var url = new UriBuilder(Url.Action("Index", "Home", new { id = "123" }, Request.Url.Scheme));
            if (filterSettings != null)
                url.Query = GetGridFilterQueryString(filterSettings); //restore grid filter settings
            return Redirect(url.ToString());
        }

        private string GetGridFilterQueryString(IGridFilterSettings settings)
        {
            var filteredColumns = settings.FilteredColumns.ToList();
            return string.Join("&", filteredColumns.Select(f => "grid-filter=" + HttpUtility.UrlEncode(f.ColumnName + "__" + (int)f.FilterType + "__" + f.FilterValue)));
        }
Dec 10, 2013 at 2:05 AM
More questions here:

For a given grid view controller, how can I retrieve current grid-filters like the sample code above?

var grid = new OrdersGrid(repository.GetAll());

Session["grid-filters"] = grid.Settings.FilterSettings; //store grid filters in the session


Thanks,

MMZ
Coordinator
Dec 11, 2013 at 3:00 AM
Hi,

Current filter settings stores in the grid.Settings.FilterSettings;
Dec 11, 2013 at 6:31 AM
Hi Bukharin,

In my controller Index action, I just use the default template generated code
Public ActionResult Index()
{
  return View(myDbContext.myTable.ToList())
}
How could I get the "grid" object and access the "Settings.FilterSettings" if I don't use "OrdersRepository" and "OrdersGrid".

Thank you
Coordinator
Dec 11, 2013 at 6:35 AM
Hi,

You can read query strin filter settings using QueryStringFilterSettings object
var settings = new QueryStringFilterSettings();
Dec 11, 2013 at 6:57 AM
Thank you very much Bukharin, I can now access the filter by the following
public ActionResult Index()
{
  var myFilterSettings = new GridMvc.Filtering.QueryStringFilterSettings();
  return View(myDbContext.myTable.ToList())
}
:-)
Dec 11, 2013 at 7:37 AM
Thanks for the reply. I have tried the above code, but it looks like the (new QueryStringFilterSettings()) is not marked as serialisable. When trying to save the current filters to session, MVC will throw an exception.

Is there any way to walk around this?

Thanks,

MMZ
Coordinator
Dec 11, 2013 at 7:51 AM
How you add settings to the session? I tried:
            var settings = new QueryStringFilterSettings();
            Session["filters"] = settings;
There is no problems
Dec 11, 2013 at 8:33 AM
Thanks for the quick reply.

I have used the similar code:

var settings = new QueryStringFilterSettings();
Session["SavedFilters"] = settings;

when the code exits from the controller, there is an exception thrown (sorry about posting the exception here, I do use session in my controller):

Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.

[SerializationException: Type 'GridMvc.Filtering.QueryStringFilterSettings' in Assembly 'GridMvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +14328213
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +408
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +420
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +532
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +270
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +814
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +322
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1487

[HttpException (0x80004005): Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.]
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +2485703
System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer) +49
System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer) +746
System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream) +336
System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled) +99
System.Web.SessionState.OutOfProcSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +3828868
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +1021
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165
Coordinator
Dec 13, 2013 at 2:43 AM
It seems that you are using SQLServer to store session state, and QueryStringFilterSettings should mark as serializable.

You need to create your own class that will stores in the session and mark them as serializable.
Similar discuss at stackoverflow - http://stackoverflow.com/questions/5889240/unable-to-serialize-the-session-state
Feb 17, 2015 at 9:42 PM
Edited Mar 4, 2015 at 7:21 PM
I know it is an old post but I ran into a similar situation whereby I was calling an Action to reload the grid but needed to maintain the page, filters and sorting. The Action was called via ajax and loaded a partial view that was basically the grid.

The grid was getting reset each time the method was called. The answer for me was to include the query string which is what is used by Grid.Mvc for those settings. Now when the ajax call to the controller was made, the partial view returned had the proper filter and paging settings, etc.

In order to help make this easier I used a trick somebody else came up with to get the query string for the current page. (I can't give credit to the creator of this because I lost the link)
            var parser = document.createElement('a');
            parser.href = window.location.href;
            var query = parser.search;
Here is the Action in the controller.
 public ActionResult ReloadGrid()
        {
            var model = CreateViewModel();
            return PartialView("RequestsGrid", model);
        }
Here is the code to call the controller. Notice the appending of the query string but also notice that the type is a "GET" and not a POST. To add in understanding, the Controller is named "T1Reconciliation" and the method is called "ReloadGrid"
function UpdateRequestGrid() {
            var parser = document.createElement('a');
            parser.href = window.location.href;
            var query = parser.search;
 
            $.ajax({
                url: '@Url.Action("ReloadGrid", "T1Reconciliation")' +  query,
                type: 'GET',
                cache: false,
                async: true,
                data: {},
                success: function (result)
                {
                    $('#requestsGrid').html(result);
                }
            });
        }
Oct 6, 2016 at 3:34 PM
How can we access grid in the code behind to querystring details grid.Settings.FilterSettings; ?