How to send an object to the Telerik MVC Grid Ajax Select() Controller Method

MattW picture MattW · Sep 15, 2011 · Viewed 9.7k times · Source

I am using the Telerik MVC Grid with Ajax binding, and am having a problem passing an object to the controller to be used to filter data. I am able to pass simple data (string, int), but not a more complex object.

For instance, I can to this no problem:

.DataBinding(dataBinding => dataBinding.Ajax().Select("_CasesAjaxBinding", "Home", new {orderId = "12345"} ))

And then in my controller, handle the orderId like this:

public ActionResult _CasesAjaxBinding(string orderId)

The problem I am having is when I try to pass a more complex object (in this case the @Model) to the controller, like this (The @Model is type CaseFilterModel):

.DataBinding(dataBinding => dataBinding.Ajax().Select("_CasesAjaxBinding", "Home", new {filterSpec = @Model} ))

And then trying to handle the object, like this:

public ActionResult _CasesAjaxBinding(CaseFilterModel filterSpec)

The filterSpec parameter is always null.

Thanks in advance for any ideas!

Answer

Christophe Geers picture Christophe Geers · Sep 15, 2011

As far as I can find on the Telerik forums this cannot be done this way. There was a similar question on there, which described exactly the same problem. When passing the model it was always null in the controller's action method.

However there is a workaround if you want to pass multiple parameters to the select method in order to filter the data, but it requires some client side coding.

I'll include a summary of that work around here, so that the answer is complete. A solemn link doesn't say much.

Assume we have a grid which displays orders items (articles) from all the orders. First make sure to hook up the client side onDataBinding event:

<%= Html.Telerik().Grid<Order>()
        .Name("Grid")
        .ClientEvents(events => events.OnDataBinding("onDataBinding"))
        .DataBinding(dataBinding => dataBinding.Ajax()
                                               .Select("_AjaxBinding", "Grid"))
%>

In the client side event handler you need to compose your select URL. Here I'll pass two parameters, an order id (int) and a description of an article (string).

<script type="text/javascript">

    function onDataBinding(e) {
        var orderId = 100;
        var searchText = "test";
        var params = { OrderId: orderId, ArticleDescription: searchText };
        var paramsStr = $.param(params);
        var selectUrl = "<%= @Url.Action("_AjaxFilterBinding", "Grid") %>" 
            + "?" + paramsStr;
        var grid = $('#Grid').data('tGrid');
        grid.ajax.selectUrl = selectUrl;
    } 

</script>

Then in your controller you can declare the select method as follows:

[GridAction]
public ActionResult _AjaxFilterBinding(AjaxFilterBindingModel model)
{
    // Retrieve data here and filter it based upon the data present in the model.
    var data = ...;

    return View(new GridModel<Order> { Data = data });
}

The model looks like:

public class AjaxFilterBindingModel
{
    public int OrderId { get; set; }
    public string ArticleDescription { get; set; }
}

Passing a collection via the URL (GET) is also possible. Let's assume you want a collection of order IDs instead of just one.

The model would look like this:

public class AjaxFilterBindingModel
{
    public IEnumerable<int> OrderIds { get; set; }
    public string ArticleDescription { get; set; }
}

And the JavaScript would look like this:

    function onDataBinding(e) {
        jQuery.ajaxSettings.traditional = true;
        var intArray = [1, 2, 3, 4, 5];
        var params = {  OrderIds: intArray, ArticleDescription: "Test" };
        var paramsStr = $.param(params);
        var selectUrl = "<%= @Url.Action("_AjaxFilterBinding", "Home") %>" + "?" 
            + paramsStr;
        var grid = $('#Grid').data('tGrid');
        grid.ajax.selectUrl = selectUrl;
    }

Remark: Don't forget to set "jQuery.ajaxSettings.traditional = true;" or the parameters will be serialized incorrectly and the ASP.NET MVC model binder will not be able to bind the integer array.

And to be complete here is the Telerik forum thread I mentioned:

http://www.telerik.com/community/forums/aspnet-mvc/grid/getting-the-model-object-in-a-custom-binding-grid-ajax-controller.aspx

And the suggested work around:

http://www.telerik.com/community/forums/aspnet-mvc/grid/code-sample-sending-additional-filters-with-ajax-binding.aspx