Hello all,
Package id: Telerik.UI.for.AspNet.Mvc5.Trial, version="2017.2.621", targetFramework="net461"
OS: Windows 7 Professional
browser version: Google Chrome, Version 60.0.3112.113 (Official Build) (64-bit)
Environment: Visual Studio Professional 2017, Asp.Net mvc 5
This is probably a simple question, but I can't seem to find an answer for it. In a nutshell, I would like to create a a Kendo UI grid in an Asp.net MVC 5 application that receives data from a WebApi without having any WebApi (server side) kendo code.
For example, this is my current implementation (that works).
(1) I have an Asp.net Mvc 5 web application that has the client side code:
Index.cshtml
@(Html.Kendo().Grid<
DataManager.Models.CommodityCodesViewModels.IndexViewModel
>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.CommodityCodeId);
columns.Bound(c => c.CommodityCode).Width(100);
columns.Bound(c => c.Description).Width(100);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(172);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
.HtmlAttributes(new { style = "height: 700px;" })
.Scrollable(s => s.Height(700))
.Groupable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(m =>
{
m.Id(c => c.CommodityCodeId);
m.Field(c => c.CommodityCodeId).Editable(false);
m.Field(c => c.CommodityCode);
m.Field(c => c.Description);
})
.Events(events => events.Error("error_handler"))
.Create(create => create.Action("CommodityCodes_Add", "CommodityCodes"))
.Read(read => read.Action("CommodityCodes_Read", "CommodityCodes"))
.Update(update => update.Action("CommodityCodes_Edit", "CommodityCodes"))
.Destroy(destroy => destroy.Action("CommodityCodes_Delete", "CommodityCodes"))
)
)
CommodityCodesController.cs
public class CommodityCodesController : Controller
{
public CommodityCodesController()
{
}
public ActionResult Index()
{
return View();
}
public async Task<
ActionResult
> CommodityCodes_Read( [DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
return Json(await new CommodityCodeHelpers().ApiGetAll(request, model) );
}
[HttpPost]
public async Task<
ActionResult
> CommodityCodes_Add([DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
if (model != null && ModelState.IsValid)
{
HttpResponseMessage message = await new CommodityCodeHelpers().ApiPost(request, model);
}
return Json(new[] { model }.ToDataSourceResult(request, ModelState));
}
[HttpPost]
public async Task<
ActionResult
> CommodityCodes_Edit([DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
if (model != null && ModelState.IsValid)
{
HttpResponseMessage message = await new CommodityCodeHelpers().ApiPut(request, model);
}
return Json(new[] { model }.ToDataSourceResult(request, ModelState));
}
[HttpPost]
public async Task<
ActionResult
> CommodityCodes_Delete([DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
if (model != null && ModelState.IsValid)
{
HttpResponseMessage message = await new CommodityCodeHelpers().ApiDelete(request, model);
}
return Json(new[] { model }.ToDataSourceResult(request, ModelState));
}
}
CommodityCodeHelpers.cs
public class CommodityCodeHelpers
{
private string _uriBase = System.Configuration.ConfigurationManager.AppSettings.Get("CommodityCodesUriBase");
private string _uriPath = System.Configuration.ConfigurationManager.AppSettings.Get("CommodityCodesUriPath");
public async Task<
DataSourceResult
> ApiGetAll([DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
List<
IndexViewModel
> modelList = new List<
IndexViewModel
>();
using (var client = new HttpClient()) // does this support socket reuse?
{
client.BaseAddress = new Uri(_uriBase);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage Res = await client.GetAsync(_uriPath);
if (Res.IsSuccessStatusCode)
{
//Storing the response details recieved from web api
var response = Res.Content.ReadAsStringAsync().Result;
modelList = JsonConvert.DeserializeObject<
List
<IndexViewModel>>(response);
}
return modelList.ToDataSourceResult(request);
}
}
public async Task<
HttpResponseMessage
> ApiPost([DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
using (var client = new HttpClient()) // does this support socket reuse?
{
client.BaseAddress = new Uri(_uriBase);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsJsonAsync(_uriPath, model);
if (response.IsSuccessStatusCode)
{
// maybe a redirect?
}
return response;
}
}
public async Task<
HttpResponseMessage
> ApiPut([DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
using (var client = new HttpClient()) // does this support socket reuse?
{
client.BaseAddress = new Uri(_uriBase);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PutAsJsonAsync(_uriPath + "//" + model.CommodityCodeId, model);
if (response.IsSuccessStatusCode)
{
// maybe a redirect?
}
return response;
}
}
public async Task<
HttpResponseMessage
> ApiDelete([DataSourceRequest] DataSourceRequest request, IndexViewModel model)
{
using (var client = new HttpClient()) // does this support socket reuse?
{
client.BaseAddress = new Uri(_uriBase);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.DeleteAsync(_uriPath + "//" + model.CommodityCodeId);
if (response.IsSuccessStatusCode)
{
// maybe a redirect?
}
return response;
}
}
}
So, right now the grid is created in my Index view, and is handled in my MVC controller. My MVC controller builds an HttpClient and then consumes my WebApi, and everything works fine.
Is there a way to use the Kendo().Grid HTML helper to consume the Web Api, while still using my Asp.net MVC controllers. Essentially, I would like to eliminate the need for me to build an Http Client to consume the Web Api, and instead have Kendo().Grid do it for me.
Thanks for all the help!
RC