I'm attempting to test out how the Telerik (Kendo) grid will work in a current application I have but am running into some roadblocks.
I have a WebApi controller which inherits from ApiController and implements the following "Get" method:
[System.Web.Http.HttpGet, System.Web.Http.Route(LookupUrl.MyLookup)] public DataSourceResult Get([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))]DataSourceRequest request)
{
return service.GetModels().ToDataSourceResult(request);
}
and in the .cshtml file I have:
@(Html.Kendo().Grid<MyModel>() .Name("telerikGrid") .Columns(col => { col.Bound(c => c.Key); col.Bound(c => c.DisplayName); col.Bound(c => c.Inactive); }) .Scrollable() .Groupable() .Sortable() .Filterable() .Pageable(pageable => pageable .Refresh(true) .PageSizes(true) .ButtonCount(5)) .DataSource(d => d.WebApi() .Model(model => { model.Id(p => p.Key); }) .Events(events => events.Error("error_handler")) .Read(read => read.Url(Url.ApiUrl(LookupUrl.MyLookup))) ) )
The grid shows up correctly on the page, but the controller method is never accessed. I'm not entirely sure what I am doing wrong here.
5 Answers, 1 is accepted
Update...again. I added code to my .cshtml file to see where the response was going (other than into the abyss):
@(Html.Kendo().Grid<Helion.Orcats.Models.Workflow.WorkflowUser>() .HtmlAttributes(new Dictionary<string, object> { { "style", "width: 700px;" } })
.Name("WorkflowUsers")
.Columns(col => {
col.Bound(c => c.UserKey);
col.Bound(c => c.DisplayName);
col.Bound(c => c.Inactive); })
.Scrollable()
.Groupable()
.Sortable()
.Filterable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(d =>
d.WebApi()
.Model(m => { m.Id(p => p.UserKey); })
.Read(read => read.Url(Url.ApiUrl(LookupUrl.WorkflowUsers_T)))
.Events(events => {
events.Error("error_handler");
events.Sync("sync_handler");
events.RequestEnd("request_end");
}) ))
When the request ends, I use a console.log to see what is in the argument and he data is there. How do I make sure that data gets set as the data source for the grid?
One of the main functionalities of the ToDataSourceResult extension method is to create a Data property in the response object. The DataSource expects this property to be named "Data" with capital D. If for some reason the data property (where items are stored in the response) is named with small letters the DataSource will not find the items.
Such situation can occur in ASP.NET Core. By default the json output is camelCase, but the "Data" is PascalCase. In our Getting Started article and specifically step 4
// Maintain property names during serialization. See:services .AddMvc() .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());// Add Kendo UI services to the services containerthe JSON serializer settings are changed to avoid this problem.
Regards,
Boyan Dimitrov
Progress Telerik
One of the main functionalities of the ToDataSourceResult extension method is to create a Data property in the response object. The DataSource expects this property to be named "Data" with capital D. If for some reason the data property (where items are stored in the response) is named with small letters the DataSource will not find the items.
Such situation can occur in ASP.NET Core. By default the output is camelCase, but the "Data" is PascalCase. In our Getting Started article and specifically step 4
// Maintain property names during serialization. See:services .AddMvc() .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());// Add Kendo UI services to the services containerthe JSON serializer settings are changed to avoid this problem.
Regards,
Boyan Dimitrov
Progress Telerik
[/quote]
While you are correct (I figured it out last night) that the problem was in the JSON data in the response, globally changing the case to Pascal Case would break the rest of the application. I ended up intercepting the response and changing the contract resolver locally. I am trying to find a more ".NET" way of doing it, but until then the following code fixed it:
[System.Web.Http.HttpGet, System.Web.Http.Route(LookupUrl.MyModels)] public HttpResponseMessage Get([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))]DataSourceRequest request) { return Request.CreateResponse(HttpStatusCode.OK, service.MyModels().ToDataSourceResult(request), GetFormatter()); } private JsonMediaTypeFormatter GetFormatter() { var f = new JsonMediaTypeFormatter { SerializerSettings = new JsonSerializerSettings {ContractResolver = new DefaultContractResolver()} }; return f; }public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver(); }