The following example demonstrates how to create a dynamic Grid that binds to a DataTable.
Razor
@modelSystem.Data.DataTable@(Html.Kendo().Grid<dynamic>().Name("Grid").Columns(columns =>{foreach(System.Data.DataColumn column in Model.Columns){var c = columns.Bound(column.ColumnName);}}).Scrollable().Height(400).Pageable().Sortable().Filterable().DataSource(dataSource => dataSource
.Ajax().PageSize(20).Model(model =>{foreach(System.Data.DataColumn column in Model.Columns){var field = model.Field(column.ColumnName, column.DataType);}}).Read(read => read.Action("Customers_Read","Grid"))))
Razor
@addTagHelper*, Kendo.Mvc@modelSystem.Data.DataTable<kendo-gridname="Grid"height="400"><datasourcetype="DataSourceTagHelperType.Ajax"page-size="20"><schemadata="Data"total="Total"errors="Errors">@{var id = Model.PrimaryKey[0].ColumnName;}<modelid="@id"><fields>@{foreach(System.Data.DataColumn column in Model.Columns){<fieldname="@column.ColumnName"type="@column.DataType"></field>}}</fields></model></schema><transport><readurl="@Url.Action("Customers_Read","Grid")"/></transport></datasource><columns>@{foreach(System.Data.DataColumn column in Model.Columns){<columnfield="@column.ColumnName"/>}}</columns><pageableenabled="true"/><sortableenabled="true"/><filterableenabled="true"/><scrollableenabled="true"/></kendo-grid>
C#
publicActionResultIndex(){DataTable products =GetDataTable(500);returnView(products);}privatestaticDataTableGetDataTable(int howMany){var dataSource =newDataTable();
dataSource.Columns.Add("Field1");
dataSource.Columns.Add("Field2",typeof(int));for(int i =0; i < howMany; i++){
dataSource.Rows.Add("value"+ i, i);}return dataSource;}publicJsonResultCustomers_Read([DataSourceRequest]DataSourceRequest request){returnJson(GetDataTable(500).ToDataSourceResult(request));}
Since dynamic editing is not part of the official built-in options, which utilized strongly typed models for ASP.NET Core, there are different solutions that can be applied.
First, add the model Id() option—the primary key of the table. Also, use the Editable() option to specify the non-editable fields.
Razor
.Model(model =>{var id = Model.PrimaryKey[0].ColumnName;
model.Id(id);foreach(System.Data.DataColumn column in Model.Columns){var field = model.Field(column.ColumnName, column.DataType);if(column.ColumnName == id){
field.Editable(false);}}})
Razor
<datasourcetype="DataSourceTagHelperType.Ajax"page-size="20"><schemadata="Data"total="Total">@{var id = Model.PrimaryKey[0].ColumnName;}<modelid="@id"><fields>@{foreach(System.Data.DataColumn column in Model.Columns){if(column.ColumnName == id){<fieldname="@column.ColumnName"type="@column.DataType"editable="false"></field>}else{<fieldname="@column.ColumnName"type="@column.DataType"></field>}}}</fields></model></schema></datasource>
Use IFormCollection to intercept the updated data item on the server.
publicstaticDataTable db =newDataTable();publicIActionResultIndex(){
db =GetDataTable(50);returnView(db);}privateDataTableGetDataTable(int howMany){DataTable dt =GetDataTableColumns();for(int i =0; i < howMany; i++){int index = i +1;DataRow row = dt.NewRow();
row["OrderID"]= index;
row["OrderDate"]=newDateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,0,0,0).AddHours(index);
row["Freight"]= index *0.1+ index *0.01;
row["ShipName"]="Name "+ index;
row["ShipCity"]="City "+ index;
row["ShipCountry"]="Country "+ index;
dt.Rows.Add(row);}return dt;}publicJsonResultCustomers_Read([DataSourceRequest]DataSourceRequest request){returnJson(db.ToDataSourceResult(request));}publicJsonResultCustomers_Update([DataSourceRequest]DataSourceRequest request,IFormCollection data){var dt =GetDataTableColumns();var updatedRow = dt.NewRow();for(int i =0; i < db.Rows.Count; i++){var itemToBeUpdatedId = data[db.PrimaryKey[0].ToString()][0];var row = db.Rows[i];if(row[db.PrimaryKey[0]].ToString()== itemToBeUpdatedId){for(var j =0; j < db.Columns.Count; j++){if(data[db.Columns[j].ColumnName][0]!=null){TypeConverter typeConverter = TypeDescriptor.GetConverter(db.Columns[j].DataType);
row[db.Columns[j].ColumnName]= typeConverter.ConvertFromString(data[db.Columns[j].ColumnName][0]);
updatedRow[db.Columns[j].ColumnName]= row[db.Columns[j].ColumnName];}}}}returnJson(dt.ToDataSourceResult(request));}privateDataTableGetDataTableColumns(){DataTable dt =newDataTable();
dt.Columns.Add(newDataColumn("OrderID",typeof(int)));
dt.Columns.Add(newDataColumn("OrderDate",typeof(DateTime)));
dt.Columns.Add(newDataColumn("Freight",typeof(decimal)));
dt.Columns.Add(newDataColumn("ShipName",typeof(string)));
dt.Columns.Add(newDataColumn("ShipCity",typeof(string)));
dt.Columns.Add(newDataColumn("ShipCountry",typeof(string)));
dt.PrimaryKey =newDataColumn[]{ dt.Columns["OrderID"]};return dt;}
Alternatively, you can post the Model and values to the server in the desired format, so that you can process them and update the corresponding table accordingly.
Razor
@(Html.Kendo().Grid<dynamic>().Name("gridMetadata").Events(events => events.Save("savePopUpChange"))// Handle the "Save" event of the Grid..Editable(ed=>ed.Mode(GridEditMode.PopUp))...// Additional configuration..DataSource(dataSource => dataSource
.Ajax()...// Additional configuration..Update(update => update.Action("Metadata_Update","Grid").Data("updateValuesData"))// Send additional data through the Update request.))
The following example shows how to create a dynamic Grid in a Razor Pages scenario.
Razor
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@Html.AntiForgeryToken()<script>functionsendTokens(){return kendo.antiForgeryTokens();}</script>
@(Html.Kendo().Grid<dynamic>().Name("Grid").Columns(columns =>{foreach(System.Data.DataColumn column in Model.DataTable.Columns){var c = columns.Bound(column.ColumnName);}}).DataSource(dataSource => dataSource
.Ajax().Model(model =>{foreach(System.Data.DataColumn column in Model.DataTable.Columns){var field = model.Field(column.ColumnName, column.DataType);}}).Read(r => r.Url(Url.Page("Index","Read")).Data("sendTokens"))))
Razor
@injectMicrosoft.AspNetCore.Antiforgery.IAntiforgery Xsrf@Html.AntiForgeryToken()<script>functionsendTokens(){return kendo.antiForgeryTokens();}</script><kendo-gridname="Grid"height="400"><datasourcetype="DataSourceTagHelperType.Ajax"page-size="20"><schemadata="Data"total="Total"errors="Errors">@{var id = Model.DataTable.PrimaryKey[0].ColumnName;}<modelid="@id"><fields>@{foreach(System.Data.DataColumn column in Model.DataTable.Columns){<fieldname="@column.ColumnName"type="@column.DataType"></field>}}</fields></model></schema><transport><readurl="/Index?handler=Read"data="sendTokens"/></transport></datasource><columns>@{foreach(System.Data.DataColumn column in Model.DataTable.Columns){<columnfield="@column.ColumnName"/>}}</columns><pageableenabled="true"/><scrollableenabled="true"/></kendo-grid>
C#
[BindProperty]publicDataTable DataTable {get;set;}publicvoidOnGet(){
DataTable =GetDataTable(500);}privatestaticDataTableGetDataTable(int howMany){var dataSource =newDataTable();
dataSource.Columns.Add("Field1");
dataSource.Columns.Add("Field2",typeof(int));for(int i =0; i < howMany; i++){
dataSource.Rows.Add("value"+ i, i);}return dataSource;}publicJsonResultOnPostRead([DataSourceRequest]DataSourceRequest request){returnnewJsonResult(GetDataTable(500).ToDataSourceResult(request));}