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.
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)
)
)