Search code examples
c#.netkendo-uikendo-gridkendo-asp.net-mvc

Unable to bind it to my Grid to a Telerik OpenAccess DataSource


Im developing an application using ASP.MVC, Kendo and OpenAccess.

After created a custom property for an specific entity, I'm trying unsuccessfully to bind it to my Datasource and Grid.

Partial Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ErpMvc.OpenAccess
{
    public partial class Customer
    {
        public string CustomProperty
        {
            get
            {
                return "My Custom Property Text";
            }
        }
    }
}

Service

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ErpMvc.OpenAccess;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;

namespace ErpMvc.Services
{
    public class CustomerService
    {
        public static IEnumerable<Customer> GetCustomers()
        {
            var dbContext = new EntitiesModel();

            return dbContext.Customers.Select(customer => new Customer
            {
                CustomerID = customer.CustomerID,
                FirstName = customer.FirstName,
                CustomProperty = customer.CustomProperty
            });

        }
    }
}

View

@model IEnumerable<ErpMvc.OpenAccess.Customer>

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@(Html.Kendo().Grid(Model)
    .Name("Customers")
    .Columns(columns =>
    {
        columns.Bound(c => c.FirstName).Title("First Name");
        columns.Bound(c => c.CustomProperty).Title("Custom Property");
    })
    .Pageable()
    .Sortable()
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id(customerID => customerID.CustomerID))
        .Read(read => read.Action("Customers_Read", "Customer"))
        .Update(update => update.Action("Customers_Update", "Customer"))
        .PageSize(50)
     )
)

Controller

public ActionResult Customers_Read([DataSourceRequest] DataSourceRequest request)
{
    return Json(CustomerService.GetCustomers().ToDataSourceResult(request));
}
  • Error messages I'm getting from VS

  • Property or indexer 'CustomProperty' cannot be assigned to -- it is read only

  • After defined a "set{}" on my CustomProperty, this error messages was resolved but I started get this other one

  • (...) If 'CustomProperty' is a property please add the FieldAlias or Storage attribute to it or declare it as a field's alias.


Solution

  • Don't use your OpenAccess objects in the view.

    Try something like this (I've not tested this, just going by memory):

    ViewModel:

    Define a new class which contains all data the view requires.

    namespace ErpMvc.ViewModel
    {
        public class Customer
        {
            public int CustomerID { get; set; }
            public string FirstName { get; set; }
            public string CustomProperty { get; set; }
        }
    }
    

    Service:

    The service needs to retrieve the data using OpenAccess, then transfer this data to the view model.

    public static IQueryable<Customer> GetCustomers()
    {
        IQueryable<Customer> result = null;
        using(var dbContext = new EntitiesModel()) 
        {
            result = dbContext.Customers.Select(customer => new ViewModel.Customer
            {
                CustomerID = customer.CustomerID,
                FirstName = customer.FirstName,
                CustomProperty = customer.CustomProperty
            });
            return result;        
        }
    }
    

    Controller:

    public ActionResult Customers_Read([DataSourceRequest] DataSourceRequest request)
    {
        return Json(CustomerService.GetCustomers().ToDataSourceResult(request));
    }
    

    View:

    The model is not passed into the grid constructor, since you're using Read(). This also means you don't need to define the model at the top of the view.

    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    @(Html.Kendo().Grid<ErpMvc.ViewModel.Customer>()
        .Name("Customers")
        .Columns(columns =>
        {
            columns.Bound(c => c.FirstName).Title("First Name");
            columns.Bound(c => c.CustomProperty).Title("Custom Property");
        })
        .Pageable()
        .Sortable()
        .Editable(editable => editable.Mode(GridEditMode.InLine))
        .DataSource(dataSource => dataSource
            .Ajax()
            .Model(model => model.Id(customerID => customerID.CustomerID))
            .Read(read => read.Action("Customers_Read", "Customer"))
            .Update(update => update.Action("Customers_Update", "Customer"))
            .PageSize(50)
         )
    )