This is a migrated thread and some comments may be shown as answers.

Kendo Grid- Web Api Consume in MVC application

1 Answer 353 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Ruben
Top achievements
Rank 1
Ruben asked on 15 Sep 2017, 02:36 PM

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

1 Answer, 1 is accepted

Sort by
0
Stefan
Telerik team
answered on 19 Sep 2017, 07:30 AM
Hello Ruben,

Thank you for the provided details and the code.

The Kendo UI Grid for MVC can work without HttpClient, as it expects the data from the controller and it is not directly connected to the HttpClient.

The Grid can directly call an API using a custom transport, but then the controller will not be called:

http://docs.telerik.com/aspnet-mvc/getting-started/custom-datasource#custom-datatype-crud-operations-setup

I can suggest checking our example for the editable Grid where the implementation of the controllers and the services are available:

http://demos.telerik.com/aspnet-mvc/grid/editing

All of the demos are available in one runnable sample application, where the code can be observed and different scenarios can be tested:

http://docs.telerik.com/aspnet-mvc/introduction#sample-application

If additional information is needed, on this matter, please let me know and I will gladly assist further.

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Grid
Asked by
Ruben
Top achievements
Rank 1
Answers by
Stefan
Telerik team
Share this question
or