Kendo grid gets null object on create/update/delete - kendo-ui

I tried a simple Kendo UI grid with CRUD operations with an Employee class. But when I create/update/delete, the employee object in the controller doesn't get the respective value and Id sets to 0 on all the operations
<div id="grid"></div>
<script>
$(document).ready(function () {
var crudServiceBaseUrl = "Components/",
dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: {
url: crudServiceBaseUrl + "GetEmployees",
dataType: "json"
},
update: {
url: crudServiceBaseUrl + "UpdateEmployee",
dataType: "json",
type: "Post"
},
destroy: {
url: crudServiceBaseUrl + "DeleteEmployee",
dataType: "json",
type: "Post"
},
create: {
url: crudServiceBaseUrl + "CreateEmployee",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST",
},
parameterMap: function (data, type) {
return kendo.stringify(data);
},
},
batch: true,
pageSize: 20,
type: "json",
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
fields: {
Id: { editable: false, nullable: true },
FullName: { validation: { required: true } },
Designation: { validation: { required: true } },
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [
{ field: "Id" },
{ field: "FullName" },
{ field: "Designation" },
{ command: ["edit", "destroy"], title: " ", width: "160px" }],
editable: "popup"
});
});
</script>
and here are the controller actions.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateEmployee([DataSourceRequest] DataSourceRequest request, Employee employee)
{
if (employee != null && ModelState.IsValid)
{
using (EmployeeDBDataContext context = new EmployeeDBDataContext())
{
EmployeeTable newEmployee = new EmployeeTable();
newEmployee.FullName = employee.FullName;
newEmployee.Designation = employee.Designation;
context.EmployeeTables.InsertOnSubmit(newEmployee);
context.SubmitChanges();
}
}
return Json(new[] { employee }.ToDataSourceResult(request, ModelState));
}
public ActionResult GetEmployees([DataSourceRequest] DataSourceRequest request)
{
var lstConfiguredEmails = new List<Employee>();
using (EmployeeDBDataContext context = new EmployeeDBDataContext())
{
lstConfiguredEmails = (from e in context.EmployeeTables
select new Employee
{
Id = e.Id,
FullName = e.FullName,
Designation = e.Designation
}).ToList();
}
return Json(lstConfiguredEmails.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult DeleteEmployee([DataSourceRequest] DataSourceRequest request, Employee employee)
{
if (employee != null)
{
using (EmployeeDBDataContext context = new EmployeeDBDataContext())
{
EmployeeTable deleteEmployee = (from e in context.EmployeeTables
where e.Id == employee.Id
select e).SingleOrDefault();
context.EmployeeTables.DeleteOnSubmit(deleteEmployee);
context.SubmitChanges();
}
}
return Json(ModelState.ToDataSourceResult());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateEmployee([DataSourceRequest] DataSourceRequest request, Employee employee)
{
if (employee != null && ModelState.IsValid)
{
using (EmployeeDBDataContext context = new EmployeeDBDataContext())
{
EmployeeTable updateEmployee = (from e in context.EmployeeTables
where e.Id == employee.Id
select e).SingleOrDefault();
updateEmployee.Id = employee.Id;
updateEmployee.FullName = employee.FullName;
updateEmployee.Designation = employee.Designation;
context.SubmitChanges();
}
}
return Json(ModelState.ToDataSourceResult());
}
and the model class
public class Employee
{
public int Id { get; set; }
public string FullName { get; set; }
public string Designation { get; set; }
}
Everytime on pressing Create/Update/Detele, the employee value in controller actions comes as,
Id = 0;
FullName = null;
Designation = null;
Please give solution.
When I used tbe grid with the code below
#(Html.Kendo().Grid<Employee>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.Id);
columns.Bound(p => p.FullName);
columns.Bound(p => p.Designation);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(160);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.Id))
.Create(update => update.Action("CreateEmployee", "Components"))
.Read(read => read.Action("GetEmployees", "Components"))
.Update(update => update.Action("UpdateEmployee", "Components"))
.Destroy(update => update.Action("DeleteEmployee", "Components"))
)
)
it works perfectly with the same controller actions.

The issue is resolved by removing batch: true from Datasource.

Try setting transport.create.contentType to "application/json". It might just be that it is sending the server the wrong content type so the server doesn't know how to parse it.

Related

Kendo treeview HierarchicalDataSource not showing child nodes

I have a kendo Treeview which is showing the parent nodes but the child nodes are not seen. Can anyone tell me where am i going wrong. I am new to this concept. I followed the below link but its not working.
http://demos.telerik.com/kendo-ui/treeview/remote-data-binding
function treeView() {
var treeM = new kendo.data.HierarchicalDataSource({
schema: {
data: function (response) {
console.log("response" + JSON.stringify(response));
var rdata = {};
if (response.d) {
rdata = JSON.parse(response.d);
}
else {
rdata = response;
}
return rdata; // ASMX services return JSON in the following format { "d": <result> }.
},
model: {
hasChildren: true,
id: "ID",
expanded: true,
fields: {
ID: { editable: false, nullable: false, type: "string" },
LINK: { editable: true, nullable: true, type: "string" },
},
},
},
transport: {
read: {
url: "/getParent",
contentType: "application/json; charset=utf-8",
type: "POST",
datatype: "json"
},
parameterMap: function (data, type) {
if ((type == "update") || (type == "create") || (type == "destroy")) {
console.log('parameterMap:');
return JSON.stringify({ "LinksJson": data });
console.log(JSON.stringify(data));
} else {
return data;
}
}
}
});
$("#treeview1").kendoTreeView({
dataSource: treeM,
dataValueField: "ID",
dataTextField: ["LINK","Name"]
});
}
$("#treeview").on("click", ".k-in", function (e) {
var tree = $("#treeview").data('kendoTreeView');
tree.toggle($(e.target).closest(".k-item"));
});
$(document).ready(function () {
treeView();
});
Service:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string getParent()
{
using (var context = new Data.Entities())
{
IQueryable<ERPv2.Data.Links> dataQuery = from x in context.Links
where x.ParentID == 68
select x;
var newQry = dataQuery.AsEnumerable().Select(c => new
{
ID = c.ID,
Name = c.Name,
Children = HasChildren(231)
});
JavaScriptSerializer JSON = new JavaScriptSerializer();
return JSON.Serialize(newQry);
}
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public bool HasChildren(int ID)
{
using (var context = new Data.Entities())
{
IQueryable<ERPv2.Data.Links> dataQuery = from x in contextLinks
where x.ParentID == ID
select x;
return dataQuery.AsEnumerable().Any();
}
}
Even when you try to view the child nodes, it will try to call getLinks and not the getreports.
From what i have seen , you should have only one method for getting parent and children. Can be an array inside each parent node.
Can you combine the data from GetReports method inside getlinks itsself and give it a shot.
You should try and get this working here with hardcoded values and then do configure with services.
http://docs.telerik.com/kendo-ui/api/javascript/ui/treeview#configuration-dataSource

some confusion about kendo grid databind

I have one kendo grid where i am calling databinding dynamically.
Below is the code:
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function () {
var _dataSource = new kendo.data.DataSource({
transport: {
read: {
type: "POST",
url: "/Dashboard/GetAttritionEmployeeDetailsWithColl",
dataType: "json",
contentType: "application/json"
},
parameterMap: function (options, operation) {
return JSON.stringify(options);
}
},
schema: {
data: "Data",
errors: "Errors",
total: "Total",
model: {
fields: {
Department: { type: "string" },
}
}
},
pageSize: 20,
serverPaging: true,
serverFiltering: true,
serverSorting: true
});
$("#grid").kendoGrid({
dataSource:_dataSource,
height: 550,
filterable: true,
sortable: true,
pageable: true,
columns: [{
field: "Department",
title: "Department"
}
]
});
});
</script>
</div>
and here is the function used in dashboard controller
public List<Entity.EmployeeHeadCountResponse> GetAttritionEmployeeDetailsWithColl(Entity.DashboardEmpRequest request)
{
try
{
employeeHeadCountResponseList = new List<Entity.EmployeeHeadCountResponse>();
DashboardServiceAgent client = new DashboardServiceAgent();
request.FlapName = "Attrition";
request.LoggedInStaffId = "33019";
request.RoleName = "Administrator";
client.GetDashboardEmpDetailsWithBytes(request, (s, e) =>
{
if (e.GetType() == typeof(Service.GetDashboardEmpDetailsWithBytesCompletedEventArgs))
{
Service.GetDashboardEmpDetailsWithBytesCompletedEventArgs err = (Service.GetDashboardEmpDetailsWithBytesCompletedEventArgs)e;
if (err.Error == null && err.Result != null)
{
List<Service.GenericCollection> GenColl = new List<Service.GenericCollection>();
byte[] compress = err.Result;
GenColl = PayloadHelper.CompressedBytesToObject(compress) as List<Service.GenericCollection>;
HierarchyCollection collection = new HierarchyCollection(GenColl);
ServiceResult = GenColl;
EmpCollection = collection;
var mylist = EmpCollection.ToList();
if (EmpCollection != null)
{
dict = new HierarchyCollection().FillForCategoryValues(GenColl);
Employee_Read(request2);
}
}
}
}
);
}
catch (System.Exception ex)
{
Common.InsertLogging(ex);
}
return employeeHeadCountResponseList;
}
so in this function it is getting return data from wcf services so this is asynchronous service first time it is providing null value and second time it is getting the value so whenever it is getting data i am calling Employee_Read function inside this function. but not able to display data in kendo grid.
Now my question is here do i have to call main function which is returning json??
Instead of using
public List<Entity.EmployeeHeadCountResponse> GetAttritionEmployeeDetailsWithColl(Entity.DashboardEmpRequest request)
use
public ActionResult GetAttritionEmployeeDetailsWithColl()
and Return Plain Json instead of kendoDataSourceResult as you're already converting it to kendo datasource in the JavaScript side You must use
return Json(employeeHeadCountResponseList)
this is more than enough.

Kendo & Web API using OData: ODataActionParameters is null

Using OData v3, trying to bind Kendo Grid to OData Actions.
Problem
ODataActionParameters is always null...
Here are my actions:
[EnableQuery]
[HttpPost]
public virtual IQueryable<ComparitiveLocalizableString> GetComparitiveTable(ODataActionParameters parameters)
{
string cultureCode = (string)parameters["cultureCode"];
var query = Repository.Table
.Where(x => x.CultureCode == null || x.CultureCode == cultureCode)
.GroupBy(x => x.TextKey)
.Select(grp => new ComparitiveLocalizableString
{
Key = grp.Key,
InvariantValue = grp.FirstOrDefault(x => x.CultureCode == null).TextValue,
LocalizedValue = grp.FirstOrDefault(x => x.CultureCode == cultureCode) == null ? "" : grp.FirstOrDefault(x => x.CultureCode == cultureCode).TextValue
});
return query;
}
[HttpPost]
public virtual IHttpActionResult PutComparitive(ODataActionParameters parameters)
{
string cultureCode = (string)parameters["cultureCode"];
string key = (string)parameters["key"];
var entity = (ComparitiveLocalizableString)parameters["entity"];
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (!key.Equals(entity.Key))
{
return BadRequest();
}
var existing = Repository.Table.FirstOrDefault(x => x.CultureCode == cultureCode && x.TextKey == key);
if (existing == null)
{
return NotFound();
}
existing.TextValue = entity.LocalizedValue;
Repository.Update(existing);
return Updated(entity);
}
[HttpPost]
public virtual IHttpActionResult DeleteComparitive(ODataActionParameters parameters)
{
string cultureCode = (string)parameters["cultureCode"];
string key = (string)parameters["key"];
var entity = Repository.Table.FirstOrDefault(x => x.CultureCode == cultureCode && x.TextKey == key);
if (entity == null)
{
return NotFound();
}
Repository.Delete(entity);
return StatusCode(HttpStatusCode.NoContent);
}
My OData route configuration:
var getComparitiveTableAction = builder.Entity<LocalizableString>().Collection.Action("GetComparitiveTable");
getComparitiveTableAction.Parameter<string>("cultureCode");
getComparitiveTableAction.Returns<IQueryable<ComparitiveLocalizableString>>();
var putComparitiveAction = builder.Entity<LocalizableString>().Collection.Action("PutComparitive");
putComparitiveAction.Parameter<string>("cultureCode");
putComparitiveAction.Parameter<string>("key");
putComparitiveAction.Parameter<ComparitiveLocalizableString>("entity");
putComparitiveAction.Returns<IHttpActionResult>();
var deleteComparitiveAction = builder.Entity<LocalizableString>().Collection.Action("DeleteComparitive");
deleteComparitiveAction.Parameter<string>("cultureCode");
deleteComparitiveAction.Parameter<string>("key");
deleteComparitiveAction.Returns<IHttpActionResult>();
and the config for my Kendo Grid:
var odataBaseUrl = "/odata/cms/LocalizableStrings/";
$(document).ready(function () {
$("#Grid").kendoGrid({
data: null,
dataSource: {
type: "odata",
transport: {
read: {
url: odataBaseUrl + "GetComparitiveTable",
dataType: "json",
type: "POST"
},
update: {
url: odataBaseUrl + "PutComparitive",
dataType: "json",
type: "POST"
},
destroy: {
url: odataBaseUrl + "DeleteComparitive",
dataType: "json",
type: "POST"
},
parameterMap: function (options, operation) {
if (operation === "read") {
alert(cultureCode);
return JSON.stringify({
cultureCode: cultureCode
});
}
else if (operation === "update") {
var model = models[0];
return {
cultureCode: cultureCode,
key: model.Key,
entity: model
};
}
else if (operation === "destroy") {
var model = models[0];
return {
cultureCode: cultureCode,
key: model.Key
};
}
}
},
schema: {
data: function (data) {
return data.value;
},
total: function (data) {
return data["odata.count"];
},
model: {
fields: {
Key: { type: "string", editable: false },
InvariantValue: { type: "string", editable: false },
LocalizedValue: { type: "string" }
}
}
},
batch: true,
//etc......
Where am I going wrong? How can I fix this?
It seems I just needed to add, contentType: "application/json" as per the following:
read: {
url: odataBaseUrl + "GetComparitiveTable",
dataType: "json",
contentType: "application/json",
type: "POST"
},
update: {
url: odataBaseUrl + "PutComparitive",
dataType: "json",
contentType: "application/json",
type: "POST"
},
destroy: {
url: odataBaseUrl + "DeleteComparitive",
dataType: "json",
contentType: "application/json",
type: "POST"
}

Kendo Grid not Paging data

I use Kendo Grid for my ASP.NET MVC app which uses ajax binding for the read.
It binds the data to the first page but does not show the number pages for the grid.
it shows (|< < 0 > >|).
Index.cshtml
#(Html.Kendo().Grid<Club.Areas.Admin.Models.Users>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("List1", "Home"))
.PageSize(5)
)
.Columns(columns =>
{
columns.Bound(p => p.Id).Filterable(false).Width(100);
columns.Bound(p => p.NickName).Width(100);
columns.Bound(p => p.UserVisitLastDate).Format("{0:MM/dd/yyyy}").Width(140);
columns.Bound(p => p.Mobile).Width(100);
})
.Pageable()
.Sortable()
.HtmlAttributes(new { style = "width:500px;height:430px;" })
)
HomeController
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult List1([DataSourceRequest]DataSourceRequest request)
{
List<Users> U = new List<Users>();
for (int i = 0; i < 100; i++)
{
U.Add(new Users
{
NickName = "Mehdi",
Company = "Taral",
Email = "M.Farokhtabar#Gmail.com",
Family = "FT",
HomeAddress = "Isfahan",
HomePhone = "03112332940",
IsActive = true,
Mobile = "09131025834",
Name = "Mehdi",
UserCreateDate = DateTime.Now,
UserVisitLastDate = DateTime.Now,
WebSite = "",
WorkAddress = "Mehdi",
PostalCode = "1234567890",
Id = i,
WorkPhone = "03117726250"
});
}
DataSourceResult result = U.ToDataSourceResult(request);
return Json(result,JsonRequestBehavior.AllowGet);
}
}
You will have to set serverPaging: true of the DataSource and make sure that the response from server has total field with the amount of the items.
My answer is not completely related to MVC approach, I have used this with WebAPI controller. The datasource should look something like this:
var sampleDataSource = new kendo.data.DataSource({
transport: {
read: {
url: svcSampleUrl,
contentType: "application/json; charset=utf-8",
type: "POST",
dataType: "json"
},
parameterMap: function (options) {
model.Take = options.take;
model.Skip = options.skip;
model.Sort = options.sort;
model.Filter = options.filter;
return kendo.stringify(model);
}
},
schema: {
data: "sampleDTOList",
total: "totalItems",
model: {
fields: {
ID: { type: "number" },
Label: { type: "string" },
Description: { type: "string" }
}
}
},
serverPaging: true,
serverFiltering: true,
serverSorting: true
});
The total attribute in the schema is where it gets the total number of records and calculates the number of pages to show. In your case you are receiving the data of the first page, and the grid does not know how much data there is in order to calculate the total number of pages there needs to be.

Internal Server Error on kendo grid update with ajax

i m trying to update grid with ajax but i couldn't success in passing and getting values between controler and view with ajax
When i run program its output is like that
[object Object]++error++Internal Server Error
So i need help
HomeController Function
[HttpGet]
public ActionResult RssCek(string value)
{
XDocument rssXml = new XDocument();
switch (value)
{
case "Ekonomi":
{
rssXml = XDocument.Load("http://sozcu.com.tr/rss.php");
break;
}
case "Siyaset":
{
rssXml = XDocument.Load("http://www.milliyet.com.tr/D/rss/rss/Rss_4.xml");
break;
}
case "Yaşam":
{
rssXml = XDocument.Load("http://www.milliyet.com.tr/D/rss/rss/Rss_5.xml");
break;
}
default:
{
rssXml = XDocument.Load("http://sozcu.com.tr/rss.php");
}
break;
}
var feedler = from feed in rssXml.Descendants("item")
select new Rss
{
Baslik = feed.Element("title").Value,
Link = "Oku",
Aciklama = feed.Element("description").Value
};
var valueToReturn = new JsonResult { Data = feedler };
return valueToReturn;
}
IndexView Grid Code
#Html.Kendo().Grid(Model)
.Name("Grid").Pageable()
.Columns(columns =>
{
columns.Bound(p => p.Baslik).Groupable(false);
columns.Bound(p => p.Aciklama).Encoded(false);
columns.Bound(p => p.Link).Encoded(false);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("RssCek", "Home"))
)
IndexView JavaScript Code
<script>
function select(e) {
var value = $(e.item).find("> .k-link").text();
$.ajax({
url: '#Url.Action("RssCek", "Home")',
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: { value: value},
success: function (feedler)
{
document.write(feedler);
},
error: function (request, status, error)
{document.write(request+"++"+ status+"++"+ error);}
});
}
</script>
I found problem is caused by missing JsonRequestBehavior.AllowGet
return Json(feedler, JsonRequestBehavior.AllowGet);
instead of ;
var valueToReturn = new JsonResult { Data = feedler };
return valueToReturn;

Resources