Hierarchical grid example "Invalid template" error

5 posts, 0 answers
  1. Greg
    Greg avatar
    18 posts
    Member since:
    Nov 2012

    Posted 06 Dec 2012 Link to this post

    I've been attempting to translate several Kendo UI Grid examples to VB.Net. I've been trying to get the hierarchical grid example to work.

    Can someone tell me why the code below does not work? Removing or commenting out the sub-grid allows the primary grid to work. But as soon as the sub-grid source is added I get the "Invalid template" error in the "Kendo.all.min.js" code. If I tell the IDE to continue the primary grid will display but it is empty.

    MVC 3 Razor project
    Version: 2012.3.1114
    IDE: Visual Studio 2012

    View source:
    @(Html.Kendo().Grid(Of KendoUIMvcApplication1.ViewModels.EmployeeViewModel).Name("Employees") _
        .Columns(Sub(columns)
                         columns.Bound(Function(e) e.FirstName).Width(140)
                         columns.Bound(Function(e) e.LastName).Width(140)
                         columns.Bound(Function(e) e.Title).Width(200)
                         columns.Bound(Function(e) e.Country).Width(200)
                         columns.Bound(Function(e) e.City)
                 End Sub) _
        .ClientDetailTemplateId("employeesTemplate") _
        .Pageable() _
        .DataSource(Sub(dataSource)
                            dataSource.Ajax().Read(Sub(read)
                                                           read.Action("HierarchyBinding_Employees", "Example")
                                                   End Sub)
                            dataSource.Ajax().PageSize(5)
                    End Sub) _
        .Sortable() _
        .Events(Sub(events)
                        events.DataBound("dataBound")
                End Sub))
     
    <script id="employeesTemplate" type="text/kendo-tmpl">
        @(Html.Kendo().Grid(Of KendoUIMvcApplication1.ViewModels.OrderViewModel).Name("Orders_#=EmployeeID#") _
        .Columns(Sub(columns)
                         columns.Bound(Function(o) o.OrderID).Width(101)
                         columns.Bound(Function(o) o.ShipCountry).Width(140)
                         columns.Bound(Function(o) o.ShipAddress).Width(200)
                         columns.Bound(Function(o) o.ShipName).Width(200)
                 End Sub) _
        .DataSource(Sub(dataSource)
                            dataSource.Ajax().Read(Sub(read)
                                                           read.Action("HierarchyBinding_Orders", "Example", New With {.employeeID = "#=EmployeeID#"})
                                                   End Sub)
                    End Sub) _
        .Pageable() _
        .Sortable() _
        .ToClientTemplate())
    </script>
    <script>
        function dataBound() {
            this.expandRow(this.tbody.find("tr.k-master-row").first());
        }
    </script>
    Controller source:
    Imports System.Web.Mvc
    Imports System.Linq
    Imports System.Data.Linq
     
    Imports Kendo.Mvc.Extensions
    Imports Kendo.Mvc.UI
     
    Public Class ExampleController
        Inherits System.Web.Mvc.Controller
     
        Public Function Hierarchy() As ActionResult
            Return View()
        End Function
     
        Public Function HierarchyBinding_Employees(<DataSourceRequest> request As DataSourceRequest) As ActionResult
            Return Json(GetEmployees().ToDataSourceResult(request))
        End Function
     
        Public Function HierarchyBinding_Orders(employeeID As Integer, <DataSourceRequest> request As DataSourceRequest) As ActionResult
            Return Json(GetOrders().Where(Function(order) order.EmployeeID = employeeID).ToDataSourceResult(request))
        End Function
     
        Private Shared Function GetOrders() As IEnumerable(Of ViewModels.OrderViewModel)
            Dim northwind = New NorthwindDataContext()
     
            Dim loadOptions = New DataLoadOptions()
     
            loadOptions.LoadWith(Of Order)(Function(o) o.Customer)
            northwind.LoadOptions = loadOptions
     
            Return northwind.Orders.[Select](Function(order) New ViewModels.OrderViewModel() With { _
             .ContactName = order.Customer.ContactName, _
             .OrderDate = order.OrderDate, _
             .OrderID = order.OrderID, _
             .ShipAddress = order.ShipAddress, _
             .ShipCountry = order.ShipCountry, _
             .ShipName = order.ShipName, _
             .EmployeeID = order.EmployeeID _
            })
        End Function
     
        Private Shared Function GetProducts() As IEnumerable(Of ViewModels.ProductViewModel)
            Dim northwind = New NorthwindDataContext()
     
            Return northwind.Products.[Select](Function(product) New ViewModels.ProductViewModel() With { _
             .ProductID = product.ProductID, _
             .ProductName = product.ProductName, _
             .UnitPrice = If(product.UnitPrice, 0), _
             .UnitsInStock = If(product.UnitsInStock, 0), _
             .UnitsOnOrder = If(product.UnitsOnOrder, 0), _
             .Discontinued = product.Discontinued, _
             .LastSupply = DateTime.Today _
            })
        End Function
     
        Private Shared Function GetEmployees() As IEnumerable(Of ViewModels.EmployeeViewModel)
            Dim northwind = New NorthwindDataContext()
     
            Return northwind.Employees.[Select](Function(employee) New ViewModels.EmployeeViewModel() With { _
             .EmployeeID = employee.EmployeeID, _
             .FirstName = employee.FirstName, _
             .LastName = employee.LastName, _
             .Country = employee.Country, _
             .City = employee.City, _
             .Notes = employee.Notes, _
             .Title = employee.Title, _
             .Address = employee.Address, _
             .HomePhone = employee.HomePhone _
            })
        End Function
    End Class
  2. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 10 Dec 2012 Link to this post

    Hello Greg,

    The code for the Grid in the detail template looks correct. Could you paste the invalid template error message? 

    Regards,
    Daniel
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Greg
    Greg avatar
    18 posts
    Member since:
    Nov 2012

    Posted 10 Dec 2012 Link to this post

    Warning! Incoming wall of text. ;)

    Here's is the cut and paste from the error message. I'd attach my solution but the file size limit is far too low.

    Unhandled exception at line 9, column 7277 in http://localhost:41972/Scripts/kendo/2012.3.1114/kendo.all.min.js
     
    0x800a139e - Microsoft JScript runtime error: Invalid template:'
     
        <div class="k-widget k-grid" id="Orders_#=EmployeeID#"><table cellspacing="0"><colgroup><col style="width:101px" /><col style="width:140px" /><col style="width:200px" /><col style="width:200px" /></colgroup><thead class="k-grid-header"><tr><th class="k-header" data-field="OrderID" data-title="Order ID" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=OrderID-asc">Order ID</a></th><th class="k-header" data-field="ShipCountry" data-title="Ship Country" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=ShipCountry-asc">Ship Country</a></th><th class="k-header" data-field="ShipAddress" data-title="Ship Address" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=ShipAddress-asc">Ship Address</a></th><th class="k-header" data-field="ShipName" data-title="Ship Name" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=ShipName-asc">Ship Name</a></th></tr></thead><tbody><tr class="t-no-data"><td colspan="4"></td></tr></tbody></table><div class="k-pager-wrap k-grid-pager"><a class="k-link k-state-disabled" data-page="1" href="\#" title="Go to the first page"><span class="k-icon k-i-seek-w">seek-w</span></a><a class="k-link k-state-disabled" data-page="0" href="\#" title="Go to the previous page"><span class="k-icon k-i-arrow-w">arrow-w</span></a><ul class="k-pager-numbers k-reset"><li><span class="k-state-selected" data-page="1">1</span></li></ul><a class="k-link k-state-disabled" data-page="2" href="\#" title="Go to the next page"><span class="k-icon k-i-arrow-e">arrow-e</span></a><a class="k-link k-state-disabled" data-page="1" href="\#" title="Go to the last page"><span class="k-icon k-i-seek-e">seek-e</span></a><span class="k-pager-info k-label">0 - 0 of 0 items</span></div></div><script>
     
        jQuery(function(){jQuery("\#Orders_#=EmployeeID#").kendoGrid({"columns":[{"title":"Order ID","width":"101px","field":"OrderID","encoded":true},{"title":"Ship Country","width":"140px","field":"ShipCountry","encoded":true},{"title":"Ship Address","width":"200px","field":"ShipAddress","encoded":true},{"title":"Ship Name","width":"200px","field":"ShipName","encoded":true}],"pageable":{"buttonCount":10},"sortable":true,"scrollable":false,"dataSource":{"transport":{"read":{"url":"/Example/HierarchyBinding_Orders?employeeID=#=EmployeeID#"}},"pageSize":10,"page":1,"total":0,"serverPaging":true,"serverSorting":true,"serverFiltering":true,"serverGrouping":true,"serverAggregates":true,"type":"aspnetmvc-ajax","filter":[],"schema":{"data":"Data","total":"Total","errors":"Errors","model":{"fields":{"OrderID":{"type":"number"},"ContactName":{"type":"string"},"ShipAddress":{"type":"string"},"OrderDate":{"type":"date","defaultValue":null},"ShipCountry":{"type":"string"},"ShipName":{"type":"string"},"EmployeeID":{"type":"number","defaultValue":null}}}}}});});
     
    <\/script>
     
    ' Generated code:'var o,e=kendo.htmlEncode;with(data){o='\n    <div class="k-widget&';32;k-grid" id="Orders_;o+='=EmployeeID';"><table cellspacing="0"><colgroup><col style="width:101px" /><col style="width:140px" /><col style="width:200px" /><col style="width:200px" /></colgroup><thead class="k-grid-header"><tr><th class="k-header" data-field="OrderID" data-title="Order&;o+='32;ID" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=OrderID-asc">Order ID</a></th><th class="k-header" data-field="ShipCountry" data-title="Ship&';32;Country" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=ShipCountry-asc">Ship Country</a></th><th class="k-header" data-field="ShipAddress" data-title="Ship&;o+='32;Address" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=ShipAddress-asc">Ship Address</a></th><th class="k-header" data-field="ShipName" data-title="Ship&';32;Name" scope="col"><a class="k-link" href="/Example/HierarchyBinding_Orders?employeeID=%23%3DEmployeeID%23&Orders_%23%3DEmployeeID%23-sort=ShipName-asc">Ship Name</a></th></tr></thead><tbody><tr class="t-no-data"><td colspan="4"></td></tr></tbody></table><div class="k-pager-wrap&;o+='32;k-grid-pager"><a class="k-link&';32;k-state-disabled" data-page="1" href="#" title="Go&;o+='32;to&';32;the&;o+='32;first&';32;page"><span class="k-icon&;o+='32;k-i-seek-w">seek-w</span></a><a class="k-link&';32;k-state-disabled" data-page="0" href="#" title="Go&;o+='32;to&';32;the&;o+='32;previous&';32;page"><span class="k-icon&;o+='32;k-i-arrow-w">arrow-w</span></a><ul class="k-pager-numbers&';32;k-reset"><li><span class="k-state-selected" data-page="1">1</span></li></ul><a class="k-link&;o+='32;k-state-disabled" data-page="2" href="#" title="Go&';32;to&;o+='32;the&';32;next&;o+='32;page"><span class="k-icon&';32;k-i-arrow-e">arrow-e</span></a><a class="k-link&;o+='32;k-state-disabled" data-page="1" href="#" title="Go&';32;to&;o+='32;the&';32;last&;o+='32;page"><span class="k-icon&';32;k-i-seek-e">seek-e</span></a><span class="k-pager-info&;o+='32;k-label">0 - 0 of 0 items</span></div></div><script>\n\tjQuery(function(){jQuery("#Orders_'+(EmployeeID)+'").kendoGrid({"columns":[{"title":"Order ID","width":"101px","field":"OrderID","encoded":true},{"title":"Ship Country","width":"140px","field":"ShipCountry","encoded":true},{"title":"Ship Address","width":"200px","field":"ShipAddress","encoded":true},{"title":"Ship Name","width":"200px","field":"ShipName","encoded":true}],"pageable":{"buttonCount":10},"sortable":true,"scrollable":false,"dataSource":{"transport":{"read":{"url":"/Example/HierarchyBinding_Orders?employeeID='+(EmployeeID)+'"}},"pageSize":10,"page":1,"total":0,"serverPaging":true,"serverSorting":true,"serverFiltering":true,"serverGrouping":true,"serverAggregates":true,"type":"aspnetmvc-ajax","filter":[],"schema":{"data":"Data","total":"Total","errors":"Errors","model":{"fields":{"OrderID":{"type":"number"},"ContactName":{"type":"string"},"ShipAddress":{"type":"string"},"OrderDate":{"type":"date","defaultValue":null},"ShipCountry":{"type":"string"},"ShipName":{"type":"string"},"EmployeeID":{"type":"number","defaultValue":null}}}}}});});\n<\/script>\n';}return o;'
  5. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 11 Dec 2012 Link to this post

    Hello Greg,

    From the error message it seems that the reason for the problem is the AntiXssEncoder which is enabled in the Web.config httpRuntime configuration:

    <httpRuntime targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    The spaces in the attributes are encoded and the "#" character is included which breaks the templates parsing. Removing it should resolve the problem. 

    Regards,
    Daniel
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Robert
    Robert avatar
    38 posts
    Member since:
    Feb 2012

    Posted 06 Jun 2013 Link to this post

    While removing the AntiXssEncoder will indeed solve the problem, it is a bad idea for security, and shame on Daniel for even suggesting it.

    I ran across this issue myself last night, and came up with a solution that works without disabling the AntiXssEncoder, and it can be used for any MVC control demonstrating the problem. You can find that solution here, with sample code and instructions.

    Please let me know if you have any questions or problems with the code.

    Robert McLaws
    CTO and co-founder, AdvancedREI.com
Back to Top
UI for ASP.NET MVC is VS 2017 Ready