Telerik Extensions for ASP.NET MVC

In edit mode only textboxes are shown instead of datepickers, numeric textboxes etc.

This means that no editor templates (.ascx files) have been found. Make sure you have copied the EditorTemplates from the installation location in your ~/Views/Shared folder.

MethodNotFoundException: System.Collections.Generic.IDictionary`2<System.String,System.Web.Mvc.ValueProviderResult> System.Web.Mvc.ControllerBase.get_ValueProvider()

This will occur if you are using the MVC 1 build of Telerik.Web.Mvc.dll with an ASP.NET MVC 2 application. Use the last number of the Telerik.Web.Mvc.dll assembly version in order to tell what version of ASP.NET MVC this build supports. If the last number is 135 then Telerik.Web.Mvc.dll is targeting ASP.NET MVC 1. If the last number is 235 then Telerik.Web.Mvc.dll is targetting ASP.NET MVC 2. Always use the build made specially for the ASP.NET MVC version of your choice.

Boolean columns are displayed as disabled checkboxes

When using server binding in ASP.NET MVC 2 the grid by default will render the display template for the bound field. By implementation ASP.NET 2 MVC renders disabled checkbox for boolean fields. If you prefer the text "true" or "false" to be displayed instead of disabled checkbox you can set the format of the column like this:
CopyUsing Format to suppress the display template
<%= Html.Telerik().Grid<Product>()
        .Name("Grid")
        .Columns(columns=>
        {
           // Define a boolean column and set the format
           columns.Bound(p => p.Discontinued).Format("{0}");
        })
%>

Boolean columns are displayed as disabled checkboxes and then change to "true" or "false"

This will occur if the grid is initially bound server side and then all operations (paging, sorting, filtering and grouping) are performing ajax request (ajax binding). The previous section explains why the grid renders disabled checkboxes during server binding. If you want to always show boolean values as "true" and "false" use the workaround described there. If you would like disabled checkboxes to be displayed always (even during ajax binding) you should set the client template of the boolean column(s) like this:
CopyUsing ClientTemplate to render checkbox for boolean column
<%= Html.Telerik().Grid<Product>()
        .Name("Grid")
        .Columns(columns=>
        {
           // Define a boolean column and set the ClientTemplate
           columns.Bound(p => p.Discontinued)
                  .ClientTemplate("<input type='checkbox' disabled='disabled' name='Discontinued' <#= Discontinued? \"checked='checked'\" : \"\" #> />");
        })
%>

Client templates do not appear when the grid displays initially

This occurs because client templates do not apply during server binding. In many cases the grid is initially bound server side by using either this:
CopyC#
<%= Html.Telerik().Grid(Model)
%>
or this approach:
CopyC#
<%= Html.Telerik().Grid<Order>()
        .BindTo((IEnumerable<Order>)ViewData["Orders"])
%>
However after paging, sorting or filtering client templates do get applied because the grid has been ajax bound. You can use either of the following approaches in order to deal with this situation:
  • Define a server template as well (requires at least version Q1 2010 SP1 - 2010.1.416):
    CopyDefining both server and client template
    <% Html.Telerik().Grid(Model)
           .Name("Grid")
           .Columns(columns =>
           {
              columns.Bound(o => o.OrderID)
                     .ClientTemplate("<strong>OrderID</strong>")
                     .Template(o =>
                     { %>
                          <strong><%= o.OrderID %></strong>
                       <%
                     });
           })
           .Render();
    %>
  • Avoid the initial server binding by not using the constructor which accepts datasource or remove the call of BindTo:
    BeforeAfter
    CopyC#
    <%= Html.Telerik().Grid(Model) // Model is IEnumerable<Order>
    %>
    CopyC#
    <%= Html.Telerik().Grid<Order>() // No longer passing a datasource
    %>
    CopyC#
    <%= Html.Telerik().Grid<Order>()
            .BindTo((IEnumerable<Order>)ViewData["Orders"])
    %>
    CopyC#
    <%= Html.Telerik().Grid<Order>() // No longer calling the BindTo method
    %>

The filtering menu of the grid does not appear when clicking the filter icon

This will occur if there is no ScriptRegistrar defined. The grid needs a ScriptRegistrar in order for its client-side features to work. Check No ScriptRegistrar for the solution.

InvalidOperationException: Bound columns require a field or property access expression.

This exception will be thrown if anything but member expression (field or property access) is used when defining a bound column for example:
CopyC#
columns.Bound(o => o.OrderID.ToString());
This kind of column definition is not supported. Use a template instead:
CopyC#
columns.Bound(o => o.OrderID).Template(o =>
    {
      %>
        <%= o.OrderID.ToString() %>
      <%
    }
);
or
CopyC#
columns.Template(o =>
    {
      %>
        <%= o.OrderID.ToString() %>
      <%
    }
);

All properties are displayed in the edit form (in-forms or pop-up mode)

In in-forms or pop-up mode Telerik Grid for ASP.NET MVC is creating an editor for the bound object (using Html.EditorFor<T>). As a result all editable properties of the bound object are displayed in the edit form. This behavior differs from in-line mode where only the bound properties (properties for which a column is defined) are editable. To hide properties from the grid edit form use the ScaffoldColumnAttribute:
CopyHiding properties of the model from the grid edit form
public class Product
{
    [ScaffoldColumn(false)]
    public int ProductID
    {
        get;
        set;
    }
}

Client side features no longer work after enabling grid editing

This can occur if an older version of jquery.validate.js is included. Open the jquery.validate.min.js file and verify that its version is at least 1.7. If it is older - use the version provided with the Telerik Extensions for ASP.NET MVC distribution (in the Scripts folder).

NotSupportedException: "Cannot use only server templates in Ajax or WebService binding mode. Please specify a client template as well."

Specifying only a server template (either template column or bound column with its template set) is not supported in Ajax or WebService binding. You can use one of the following workarounds:
  • Set the client template as well:
    CopyClient template
    <%= Html.Telerik().Grid(Model)
            .Name("Grid")
            .Columns(columns =>
            {
                 columns.Add(c => c.CustomerID)
                        .Template(c =>
                         {
                           %>
                               <%= Html.ActionLink("Edit", "Edit", new {id = c.CustomerID}) %>
                           <%
                         })
                        .ClientTemplate("<a href='" + Url.Action("Edit", "Home") + "/<# CustomerID #>Edit</a>")
                        .Title("Edit");
            })
    %>
  • Use Format:
    CopyUsing Format
    <%= Html.Telerik().Grid(Model)
            .Name("Grid")
            .Columns(columns =>
            {
                 columns.Add(c => c.CustomerID)
                        .Format(Html.ActionLink("Edit", "Home", new { id = "{0}"}}))
                        .Encoded(false)
                        .Title("Edit");
            })
    %>
  • Use the rowDataBound event:
    CopyTemplate using rowDataBound
    function onRowDataBound(e) {
        //`this` is the DOM element of the grid
        var grid = $(this).data('tGrid');
    
        //the DOM element (<tr>) representing the row which is being databound
    
        var row = e.row;
    
        //the data item - JSON object.
    
        var dataItem = e.dataItem;
    
        //You can use the OnRowDataBound event to customize the way data is presented on the client-side
    
        row.cells[0].innerHTML = '<a href="/Home/Edit/' + dataItem.CustomerID + '">Edit</a>';
    }
    Important
    In versions prior to 2010.1.416 (Q1 2010 SP1) you cannot speciy both server and client template. If upgrading is not an option you should set only the client template or use Format or OnRowDataBound.

Receiving "500 Internal Server Error" during Ajax binding

The reason for this error is a server side exception which occurrs during the invocation of the action method. You can use a sniffer tool such as Fiddler (for Internet Explorer) or FireBug (for Firefox) to inspect the server response which in most cases will contain the stacktrace of the exception.

A common exception is "A circular reference was detected while serializing an object of type" followed by some type name. The reason for this exception is a circular reference in the objects used to databind the grid. A common example for a circular object reference is the Orders - Customers relationship in the Northwind database:

Most O/R mapping tools would create reference properties for such type of associations. In this case the Orders object will have a Categories property and the Categories object will have an Orders prooperty (using Entity Framework):
The .NET framework Javascript serializer is unable to handle such a circular reference scenario. Apart from using server binding, if appropriate, other possible solutions are:

  1. Hide the reference properties to avoid the circular reference problem:
    • For Entity Framework you can change the visibility of the association property. Anything but "public" will do:
    • For Linq to Sql you can avoid generating the association property altogether:
  2. Use ViewModel object instead of the original object created by the O/R mapping tool. This is the recommended approach as it does not require any modifications to the model objects.
    1. Create a new class which will contain only the properties required for databinding the grid (properties mapped to grid columns that is).
      CopyOrders ViewModel
      public class OrderViewModel
      {
          public int OrderID
          {
              get;
              set;
          }
      
          public DateTime? OrderDate
          {
              get;
              set;
          }
      
          public string ShipAddress
          {
              get;
              set;
          }
      }
      Note
      If binding to EF make sure you add the key property (OrderID in this case) to the ViewModel even if you are not displaying it in the grid. Otherwise you will end up with NotSupportedException saying "Cannot find primitive type or property to sort by". This is required by the Entity Framework LINQ provider.
    2. In your view configure the grid to bind to the ViewModel type instead:
      CopyView
      <%= Html.Telerik().Grid<Models.OrdersViewModel>(Model)
                        .Name("Grid")
                        .Ajax(ajax => ajax.Action("AjaxIndex", "Home"))
      %>
    3. In your controller create ViewModel objects:
      CopyController - Returning ViewModel objects
      public ActionResult Index()
      {
          var model = from o in new NorthwindEntities().Orders
                      select new OrderViewModel
                      {
                          OrderID = o.OrderID,
                          OrderDate = o.OrderDate,
                          ShipAddress = o.ShipAddress
                      };
          return View(model);
      }
      
      [GridAction]
      public ActionResult AjaxIndex()
      {
          var model = from o in new NorthwindEntities().Orders
                      select new OrderViewModel
                      {
                          OrderID = o.OrderID,
                          OrderDate = o.OrderDate,
                          ShipAddress = o.ShipAddress
                      };
      
          return View(new GridModel
          {
              Data = model
          });
      }

    Some client-side events are not raised

    The OnRowDataBound, OnDataBinding, OnDataBound events are raised only during client-side binding (Ajax Binding or Web Service Binding). Those events are never raised during Server Binding. Make sure the grid is properly configured for Ajax Binding or Web Service Binding.

    The OnRowSelected event requires the grid to be Selectable().

    Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property

    This exception is thrown if you try to serialize too much data in JSON format (for example during Ajax or WebSerice binding). By default the maxJsonLength property is set to 2097152 characters. There are two possible solutions:
    • Try to reduce the amount of data which should be serialized. You can enable grid paging for example.
    • Increase the value of maxJsonLength by adding the following section to your web.config:
      CopyIncreasing maxJsonLength
      <system.web.extensions>  
         <scripting>  
             <webServices>  
                <jsonSerialization maxJsonLength="2147483644" />
             </webServices>  
         </scripting>  
      </system.web.extensions>
      Important
      This example is setting maxJsonLength to 2147483644 which is the maximum value allowed by the Int32 type.

    See Also