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

Display Foreign Key Name in Grid With Code First Approach

8 Answers 1472 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Lawrence
Top achievements
Rank 1
Lawrence asked on 03 May 2018, 01:26 AM

Hi

 

I am struggling to get a foreign key to display it's name in Kendo Grid. In my normal MVC views the name displays just fine.

I am using a code first approach in MVC with DBContext instead of using EDMX models.

 

Could someone please help me with this issue.

Help would be appreciated :)

 

Here is the Kendo Grid code for my view:

@(Html.Kendo().Grid<ZerothApp.Models.ProvinceViewModel>()
    .Name("grid")
    .Columns(columns =>
    {
        columns.Bound(p => p.ProvinceName).Filterable(ftb => ftb.Multi(true).Search(true));
        columns.Bound(p => p.Country).Filterable(ftb => ftb.Multi(true).Search(true));
        columns.Bound(p => p.CreatedBy);
        columns.Bound(p => p.DateCreated);
        columns.Bound(p => p.LastEditedBy);
        columns.Bound(p => p.DateLastEdited);
        columns.Template(@<text></text>).ClientTemplate("<a class='editProvince' href='" + Url.Action("Edit", "Province") + "/#=ProvinceIdentifier#'>Edit</a> | <a class='detailsProvince' href='" + Url.Action("Details", "Province") + "/#=ProvinceIdentifier#'>Details</a> | <a class='deleteProvince' href='" + Url.Action("Delete", "Province") + "/#=ProvinceIdentifier#'>Delete</a>").Title("Actions");
    })
    .Pageable()
    .Sortable()
    .Groupable()
    .Scrollable()
    .Filterable()
    .HtmlAttributes(new { style = "height:550px;" })
    .DataSource(dataSource => dataSource
        .Ajax()
        .Sort(sort => sort.Add("ProvinceName").Ascending())
        .PageSize(20)
        .Model(model =>
        {
            model.Id(p => p.ProvinceIdentifier);
            model.Field(p => p.ProvinceIdentifier).Editable(false);
            model.Field(p => p.CountryID).DefaultValue(1);
        })
        .Read(read => read.Action("GetProvinces", "Province"))
    )
                    )

 

Here is the code for my ProvinceViewModel:

public class ProvinceViewModel
    {
        public System.Guid ProvinceIdentifier { get; set; }
 
        public string ProvinceName { get; set; }
 
        public System.Guid CountryID { get; set; }
 
        public string Country { get; set; }
 
        public string CreatedBy { get; set; }
 
        public Nullable<System.DateTime> DateCreated { get; set; }
 
        public string LastEditedBy { get; set; }
 
        public Nullable<System.DateTime> DateLastEdited { get; set; }
 
        public SelectList CountriesSelectList { get; set; }
    }

 

Here is the code for my Province class:

public class Province
    {
        [Key]
        public System.Guid ProvinceIdentifier { get; set; }
 
        public string ProvinceName { get; set; }
 
        public System.Guid CountryID { get; set; }
 
        public string CreatedBy { get; set; }
 
        public Nullable<System.DateTime> DateCreated { get; set; }
 
        public string LastEditedBy { get; set; }
 
        public Nullable<System.DateTime> DateLastEdited { get; set; }
 
    }

 

Here is the code for my ProvinceController:

using System;
using ZerothApp.Models;
using System.Linq;
using System.Linq.Dynamic;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity.Owin;
using DataTables.Mvc;
using System.Collections.Generic;
using System.Net;
using System.Data.Entity;
using System.Threading.Tasks;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
 
 
namespace ZerothApp.Controllers
{
    public class ProvinceController : Controller
    {
        private ApplicationDbContext _dbContext;
 
        public ApplicationDbContext DbContext
        {
            get
            {
                return _dbContext ?? HttpContext.GetOwinContext().Get<ApplicationDbContext>();
            }
            private set
            {
                _dbContext = value;
            }
 
        }
 
        public ProvinceController()
        {
 
        }
 
        public ProvinceController(ApplicationDbContext dbContext)
        {
            _dbContext = dbContext;
        }
 
        // GET: Province
        public ActionResult Index()
        {
            return View();
        }
 
        public ActionResult GetProvinces([DataSourceRequest] DataSourceRequest request)
        {
            return Json(GetProvinceViewModels().ToDataSourceResult(request));
        }
 
        private IQueryable<ProvinceViewModel> GetProvinceViewModels()
        {
            return DbContext.Provinces
                            .Select(
                            c => new ProvinceViewModel
                            {
                                ProvinceIdentifier = c.ProvinceIdentifier,
                                ProvinceName = c.ProvinceName,
                                CountryID = c.CountryID,
                                CreatedBy = c.CreatedBy,
                                DateCreated = c.DateCreated,
                                LastEditedBy = c.LastEditedBy,
                                DateLastEdited = c.DateLastEdited
                            });
        }
 
 
        // GET: Province/Create
        public ActionResult Create()
        {
            var model = new ProvinceViewModel();
            model.CountriesSelectList = GetCountriesSelectList();
            return View("Add", model);
        }
 
        // POST: Province/Create
        [HttpPost]
        public async Task<ActionResult> Create(ProvinceViewModel provinceVM)
        {
 
            provinceVM.CountriesSelectList = GetCountriesSelectList();
 
            if (!ModelState.IsValid)
                return View("Add", provinceVM);
 
            Province province = MaptoModel(provinceVM);
 
            DbContext.Provinces.Add(province);
            var task = DbContext.SaveChangesAsync();
            await task;
 
            if (task.Exception != null)
            {
                ModelState.AddModelError("", "Unable to add the Asset");
                return View("Add", provinceVM);
            }
 
            return RedirectToAction("Index");
        }
 
        // GET: Province/Edit/5
        public ActionResult Edit(Guid id)
        {
            var province = DbContext.Provinces.FirstOrDefault(x => x.ProvinceIdentifier == id);
 
            ProvinceViewModel provinceViewModel = MapToViewModel(province);
 
            if (Request.IsAjaxRequest())
                return PartialView("Edit", provinceViewModel);
            return View(provinceViewModel);
        }
 
        // POST: Province/Edit/5
        [HttpPost]
        public async Task<ActionResult> Edit(ProvinceViewModel provinceVM)
        {
 
            provinceVM.CountriesSelectList = GetCountriesSelectList(provinceVM.CountryID);
 
            if (!ModelState.IsValid)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return View(Request.IsAjaxRequest() ? "Edit" : "Edit", provinceVM);
            }
 
            Province province = MaptoModel(provinceVM);
 
            DbContext.Provinces.Attach(province);
            DbContext.Entry(province).State = EntityState.Modified;
            var task = DbContext.SaveChangesAsync();
            await task;
 
            if (task.Exception != null)
            {
                ModelState.AddModelError("", "Unable to update the Asset");
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return View(Request.IsAjaxRequest() ? "Edit" : "Edit", provinceVM);
            }
 
            return RedirectToAction("Index");
 
        }
 
        public async Task<ActionResult> Details(Guid id)
        {
            var province = await DbContext.Provinces.FirstOrDefaultAsync(x => x.ProvinceIdentifier == id);
            var provinceVM = MapToViewModel(province);
 
            if (Request.IsAjaxRequest())
                return PartialView("Details", provinceVM);
 
            return View(provinceVM);
        }
 
        // GET: Province/Delete/5
        public ActionResult Delete(Guid id)
        {
            var province = DbContext.Provinces.FirstOrDefault(x => x.ProvinceIdentifier == id);
 
            ProvinceViewModel provinceViewModel = MapToViewModel(province);
 
            if (Request.IsAjaxRequest())
                return PartialView("Delete", provinceViewModel);
            return View(provinceViewModel);
        }
 
        // POST: Province/Delete/5
        [HttpPost, ActionName("Delete")]
        public async Task<ActionResult> DeleteProvince(Guid ProvinceIdentifier)
        {
            var province = new Province { ProvinceIdentifier = ProvinceIdentifier };
            DbContext.Provinces.Attach(province);
            DbContext.Provinces.Remove(province);
 
            var task = DbContext.SaveChangesAsync();
            await task;
 
            if (task.Exception != null)
            {
                ModelState.AddModelError("", "Unable to Delete the Province");
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                ProvinceViewModel provinceVM = MapToViewModel(province);
                return View(Request.IsAjaxRequest() ? "Delete" : "Delete", provinceVM);
            }
 
            return RedirectToAction("Index");
 
        }
 
        private SelectList GetCountriesSelectList(object selectedValue = null)
        {
            return new SelectList(DbContext.Countries
                                            .Select(x => new { x.CountryIdentifier, x.CountryName }),
                                                "CountryIdentifier",
                                                "CountryName", selectedValue);
        }
 
        private ProvinceViewModel MapToViewModel(Province province)
        {
            var country = DbContext.Countries.Where(x => x.CountryIdentifier == province.CountryID).FirstOrDefault();
 
            ProvinceViewModel provinceViewModel = new ProvinceViewModel()
            {
                ProvinceIdentifier = province.ProvinceIdentifier,
                ProvinceName = province.ProvinceName,
                CountryID = province.CountryID,
                CreatedBy = province.CreatedBy,
                DateCreated = province.DateCreated,
                LastEditedBy = province.LastEditedBy,
                DateLastEdited = province.DateLastEdited,
                Country = country != null ? country.CountryName : String.Empty,
                CountriesSelectList = new SelectList(DbContext.Countries
                                                                    .Select(x => new { x.CountryIdentifier, x.CountryName }),
                                                                      "CountryIdentifier",
                                                                      "CountryName", province.CountryID)
            };
 
            return provinceViewModel;
        }
 
        private Province MaptoModel(ProvinceViewModel provinceVM)
        {
            Province province = new Province()
            {
                ProvinceIdentifier = provinceVM.ProvinceIdentifier,
                ProvinceName = provinceVM.ProvinceName,
                CountryID = provinceVM.CountryID,
                CreatedBy = provinceVM.CreatedBy,
                DateCreated = provinceVM.DateCreated,
                LastEditedBy = provinceVM.LastEditedBy,
                DateLastEdited = provinceVM.DateLastEdited
            };
 
            return province;
        }
    }
}

 

Here is the code for my CountryViewModel:

public class CountryViewModel
    {
        [Required]
        public System.Guid CountryIdentifier { get; set; }
 
        public string CountryName { get; set; }
 
        public string CreatedBy { get; set; }
 
        public Nullable<System.DateTime> DateCreated { get; set; }
 
        public string LastEditedBy { get; set; }
 
        public Nullable<System.DateTime> DateLastEdited { get; set; }
    }

 

Here is the code for my Country class:

public class Country
    {
        [Key]
        public System.Guid CountryIdentifier { get; set; }
 
        public string CountryName { get; set; }
 
        public string CreatedBy { get; set; }
 
        public Nullable<System.DateTime> DateCreated { get; set; }
 
        public string LastEditedBy { get; set; }
 
        public Nullable<System.DateTime> DateLastEdited { get; set; }
    }

 

And here is the code for my CountriesController:

 

using System;
using ZerothApp.Models;
using System.Linq;
using System.Linq.Dynamic;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity.Owin;
using DataTables.Mvc;
using System.Collections.Generic;
using System.Net;
using System.Data.Entity;
using System.Threading.Tasks;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
 
namespace ZerothApp.Controllers
{
    public class CountryController : Controller
    {
        private ApplicationDbContext _dbContext;
 
        public ApplicationDbContext DbContext
        {
            get
            {
                return _dbContext ?? HttpContext.GetOwinContext().Get<ApplicationDbContext>();
            }
            private set
            {
                _dbContext = value;
            }
 
        }
 
        public CountryController()
        {
 
        }
 
        public CountryController(ApplicationDbContext dbContext)
        {
            _dbContext = dbContext;
        }
 
        // GET: Countries
        public ActionResult Index()
        {
            return View();
        }
 
        public ActionResult GetCountries([DataSourceRequest] DataSourceRequest request)
        {
            return Json(GetCountryViewModels().ToDataSourceResult(request));
        }
 
        private IQueryable<CountryViewModel> GetCountryViewModels()
        {
            return DbContext.Countries
                            .Select(
                            c => new CountryViewModel
                            {
                                CountryIdentifier = c.CountryIdentifier,
                                CountryName = c.CountryName,
                                CreatedBy = c.CreatedBy,
                                DateCreated = c.DateCreated,
                                LastEditedBy = c.LastEditedBy,
                                DateLastEdited = c.DateLastEdited
                            });
        }
 
 
        // GET: Countries/Create
        public ActionResult Create()
        {
            var model = new CountryViewModel();
            return View("Add", model);
        }
 
        // POST: Countries/Create
        [HttpPost]
        public async Task<ActionResult> Create(CountryViewModel countryVM)
        {
            if (!ModelState.IsValid)
                return View("Add", countryVM);
 
            Country country = MaptoModel(countryVM);
 
            DbContext.Countries.Add(country);
            var task = DbContext.SaveChangesAsync();
            await task;
 
            if (task.Exception != null)
            {
                ModelState.AddModelError("", "Unable to add the country");
                return View("Add", countryVM);
            }
 
            return RedirectToAction("Index");
        }
 
        // GET: Countries/Edit/5
        public ActionResult Edit(Guid id)
        {
            var country = DbContext.Countries.FirstOrDefault(x => x.CountryIdentifier == id);
 
            CountryViewModel countryViewModel = MapToViewModel(country);
 
            if (Request.IsAjaxRequest())
                return PartialView("Edit", countryViewModel);
            return View(countryViewModel);
        }
 
        // POST: Countries/Edit/5
        [HttpPost]
        public async Task<ActionResult> Edit(CountryViewModel countryVM)
        {
            if (!ModelState.IsValid)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return View(Request.IsAjaxRequest() ? "Edit" : "Edit", countryVM);
            }
 
            Country country = MaptoModel(countryVM);
 
            DbContext.Countries.Attach(country);
            DbContext.Entry(country).State = EntityState.Modified;
            var task = DbContext.SaveChangesAsync();
            await task;
 
            if (task.Exception != null)
            {
                ModelState.AddModelError("", "Unable to update the Asset");
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return View(Request.IsAjaxRequest() ? "Edit" : "Edit", countryVM);
            }
 
            return RedirectToAction("Index");
 
        }
 
        public async Task<ActionResult> Details(Guid id)
        {
            var country = await DbContext.Countries.FirstOrDefaultAsync(x => x.CountryIdentifier == id);
            var countryVM = MapToViewModel(country);
 
            if (Request.IsAjaxRequest())
                return PartialView("Details", countryVM);
 
            return View(countryVM);
        }
 
        // GET: Countries/Delete/5
        public ActionResult Delete(Guid id)
        {
            var country = DbContext.Countries.FirstOrDefault(x => x.CountryIdentifier == id);
 
            CountryViewModel countryViewModel = MapToViewModel(country);
 
            if (Request.IsAjaxRequest())
                return PartialView("Delete", countryViewModel);
            return View(countryViewModel);
        }
 
        // POST: Countries/Delete/5
        [HttpPost, ActionName("Delete")]
        public async Task<ActionResult> DeleteCountry(Guid CountryIdentifier)
        {
            var country = new Country { CountryIdentifier = CountryIdentifier };
            DbContext.Countries.Attach(country);
            DbContext.Countries.Remove(country);
 
            var task = DbContext.SaveChangesAsync();
            await task;
 
            if (task.Exception != null)
            {
                ModelState.AddModelError("", "Unable to Delete the country");
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                CountryViewModel countryVM = MapToViewModel(country);
                return View(Request.IsAjaxRequest() ? "Delete" : "Delete", countryVM);
            }
 
            return RedirectToAction("Index");
 
        }
 
        private CountryViewModel MapToViewModel(Country country)
        {
 
            CountryViewModel countryViewModel = new CountryViewModel()
            {
                CountryIdentifier = country.CountryIdentifier,
                CountryName = country.CountryName,
                CreatedBy = country.CreatedBy,
                DateCreated = country.DateCreated,
                LastEditedBy = country.LastEditedBy,
                DateLastEdited = country.DateLastEdited,
            };
 
            return countryViewModel;
        }
 
        private Country MaptoModel(CountryViewModel countryVM)
        {
            Country country = new Country()
            {
                CountryIdentifier = countryVM.CountryIdentifier,
                CountryName = countryVM.CountryName,
                CreatedBy = countryVM.CreatedBy,
                DateCreated = countryVM.DateCreated,
                LastEditedBy = countryVM.LastEditedBy,
                DateLastEdited = countryVM.DateLastEdited
            };
 
            return country;
        }
    }
}

8 Answers, 1 is accepted

Sort by
0
Lawrence
Top achievements
Rank 1
answered on 03 May 2018, 05:32 AM
I forgot to mention, the foreign key is the CountryID in Provinces that is linked to the CountryIdentifier in Countries
0
Alex Hajigeorgieva
Telerik team
answered on 04 May 2018, 12:22 PM
Hello, Lawrence,

The Kendo UI Grid should display the Foreign Key column automatically provided some expectations are met. Here is the official demo for your reference:

https://demos.telerik.com/aspnet-mvc/grid/foreignkeycolumn

In the demo, you will notice a column, identified as ForeignKey column which receives the Categories IEnumerable collection with the help of the ViewData:

columns.ForeignKey(p => p.CategoryID, (System.Collections.IEnumerable)ViewData["categories"], "CategoryID", "CategoryName").Title("Category").Width(200);

In your case, it should be before the return here:

public ActionResult GetProvinces([DataSourceRequest] DataSourceRequest request)
{
    return Json(GetProvinceViewModels().ToDataSourceResult(request));
}

If the column will be used for editing, the editor in ~Views/Shared/EditorTemplates is named GridForeignKey.cshtml (with the Telerik VSX help it is automatically generated) and it contains the following:

@model object
 
@(Html.Kendo().DropDownListFor(m => m)
    .BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"])
)

Have a test run and let me know if you need further assistance.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Lawrence
Top achievements
Rank 1
answered on 04 May 2018, 03:06 PM
[quote]Hello, Lawrence,

The Kendo UI Grid should display the Foreign Key column automatically provided some expectations are met. Here is the official demo for your reference:

https://demos.telerik.com/aspnet-mvc/grid/foreignkeycolumn

In the demo, you will notice a column, identified as ForeignKey column which receives the Categories IEnumerable collection with the help of the ViewData:

columns.ForeignKey(p => p.CategoryID, (System.Collections.IEnumerable)ViewData["categories"], "CategoryID","CategoryName").Title("Category").Width(200);

In your case, it should be before the return here:

public ActionResult GetProvinces([DataSourceRequest] DataSourceRequest request){    return Json(GetProvinceViewModels().ToDataSourceResult(request));}

If the column will be used for editing, the editor in ~Views/Shared/EditorTemplates is named GridForeignKey.cshtml (with the Telerik VSX help it is automatically generated) and it contains the following:

@model object
 
@(Html.Kendo().DropDownListFor(m => m)    .BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"])


Have a test run and let me know if you need further assistance.

Kind Regards,
Alex Hajigeorgieva 
Progress Telerik
[/quote]

Hello Alex

 

Thank you for the response, however I'm afraid I do not understand how to implement it. Your demo code works with EDMX Entity Framework models as where I am using a code-first approach so your code is not working with my implementation and I do not understand how to adapt the database-first code to work with code-first.

0
Accepted
Alex Hajigeorgieva
Telerik team
answered on 08 May 2018, 01:09 PM
Hi, Lawrence,

There isn't anything different in the approach that you would use in terms of Code First, you can check out the demo in the repository with examples which shows how to perform editing of a CodeFirst set up of the Kendo UI Grid:

https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/grid/editing-ef-code-first/

However, I did notice that the editing is not implemented as expected in the provided code snippet. When the grid is Ajax bound, the ActionMethods are not supposed to return the view but JSON. I am referring to the below, for example:

      // GET: Province/Create
        public ActionResult Create()
        {
            var model = new ProvinceViewModel();
            model.CountriesSelectList = GetCountriesSelectList();
            return View("Add", model);
        }
 
// I would expect to see something like this
 public ActionResult Create([DataSourceRequest] DataSourceRequest request, ProvinceViewModel provinceToAdd)
        {
            using (var dbContext = new ApplicationDbContext())
            {
                if (ModelState.IsValid)
                {
                    provinceToAdd.ProvinceIdentifier = new Guid();
                    dbContext.Provinces.Add(provinceToAdd);
                    dbContext.SaveChanges();
                }
 
                return Json(new[] { provinceToAdd }.ToDataSourceResult(request));
            }
        }

Here is more information about it:

https://docs.telerik.com/aspnet-mvc/helpers/grid/binding/ajax-binding
https://docs.telerik.com/aspnet-mvc/helpers/grid/editing/ajax-editing

Another thing I find different to what I would expect to see is the model definition, the Country model should hold a virtual collection of Provinces: 

public class Country
{
    public Country()
    {
        this.Provinces = new HashSet<Province>();
    }
 
    // own properties
 
    public virtual ICollection<Province> Provinces { get; set; }
}

As far as showing the countries text, you should populate them when the province controller is invoked in the ViewData, for example:

public ActionResult ProvinceController()
{           
    PopulateCountries();
 
    return View();
}      
 
 
 private void PopulateCountries()
{
    using (var dbContext = new ApplicationDbContext())
    {
       var countries = dbContext.Countries.Select(
                 c => new CountryViewModel
                 {
                     Name = c.Name,
                     CountryID = c.CountryID                            
                 }).ToList();
         ViewData["countries"] = countries;
         ViewData["defaultCountry"] = countries.FirstOrDefault();
    }           
}

If if you have a runnable example that I can check, I would be glad to help you where you are finding any difficulties. 

Regards,
Alex Hajigeorgieva
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Lawrence
Top achievements
Rank 1
answered on 09 May 2018, 10:55 PM

Hello Alex

Thank you for the above, it helped a lot.

All I had to do was the following:

In my ProvinceController I made the following changes:

public ActionResult Index()
        {
            PopulateCountries();
 
            return View();
        }
 
        private void PopulateCountries()
        {
            using (var dbContext = new ApplicationDbContext())
            {
                var countries = dbContext.Countries.Select(
                          c => new CountryViewModel
                          {
                              CountryName = c.CountryName,
                              CountryIdentifier = c.CountryIdentifier
                          }).ToList();
                ViewData["countries"] = countries;
                ViewData["defaultCountry"] = countries.FirstOrDefault();
            }
        }

 

And in my grid I added the column for the CountryID foreign key like this:

columns.ForeignKey(p => p.CountryID, (System.Collections.IEnumerable)ViewData["countries"], "CountryIdentifier", "CountryName").Title("Country");

 

I did not need to make any changes to my Country class. By implementing the changes to my Country class as above I got an error telling me that Country_CountryIdentifier does not exist.

0
Alex Hajigeorgieva
Telerik team
answered on 10 May 2018, 06:33 AM
Hello, Lawrence,

I am very pleased to hear that you have found my response helpful and also thank you for sharing the details of what you needed to do in your scenario. Should you face any difficulties with the foreign key column, you can reply to the thread here or submit a new one if it is not related to this topic.

I would be glad to assist you.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Breno
Top achievements
Rank 1
answered on 27 Feb 2020, 07:38 PM
You can get a list of "fathers" using ViewData, a simple solution without using join.

@model MyModel.Models.Project.Item
<h1 class="text-primary">Itens</h1>
<script type="text/javascript">
    var ls = @Html.Raw(Json.Serialize(ViewData["MyItems"]));
    function showName(e) {
        for (var i = 0; i < ls.length; i++) {
            if (e.Id == ls[i].Id) {
                return ls[i].Name
            }
        }
    }
</script>
@(Html.Kendo()
.Grid<MyModel.Models.Project.Item>()
.Name("GridItem")
.Columns(columns =>
{
    columns.ForeignKey(p => p.Id, (System.Collections.IEnumerable)ViewData["MyItems"], "Id", "Name")
        .Title("My title")
        .Width(200)
        .ClientTemplate("#= showName(data) #");
    columns.Bound(o => o.Name);
    columns.Bound(o => o.Id);
    columns.Command(command => { command.Edit(); command.Destroy(); }).Width(245).ClientHeaderTemplate("Actions");
})
.ToolBar(toolbar =>
{
    toolbar.Create().Text("New item");
})
.Events(e => e.ExcelExport("exportToExcel"))
.Filterable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable(pageable => pageable.PageSizes(true))
.Sortable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(false)
.PageSize(10)
.Model(model =>
        {
            model.Id(p => p.Id);
            model.Field(p => p.Id).Editable(false);
            model.Field(p => p.FatherId).DefaultValue(1);
        })
.Create(create => create.Action("CreateItem", "MyController"))
.Read(read => read.Action("ReadGrid", "MyController"))
.Update(update => update.Action("UpdateItem", "MyController"))
.Destroy(destroy => destroy.Action("DestroyItem", "MyController"))
)
)

"A computer is like air conditioning it becomes useless when you open windows" - reflects
0
Alex Hajigeorgieva
Telerik team
answered on 02 Mar 2020, 02:38 PM

Hello, Breno,

By using the Foreign Key column, these values are already serialized and part of the grid columns definition. It is not necessary to provide a Client template and a function.

// this should be enough to show the Name text
columns.ForeignKey(p => p.Id, (System.Collections.IEnumerable)ViewData["MyItems"], "Id", "Name").Title("My title").Width(200);

Once the column has a values array as pictured below, these are automatically used to generate the template. you can see it in the simplest jQuery example here:

https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/columns.values

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Get quickly onboarded and successful with your Telerik UI for ASP.NET MVC with the dedicated Virtual Classroom technical training, available to all active customers.
Tags
Grid
Asked by
Lawrence
Top achievements
Rank 1
Answers by
Lawrence
Top achievements
Rank 1
Alex Hajigeorgieva
Telerik team
Breno
Top achievements
Rank 1
Share this question
or