我和Daniel在本主题中遇到的问题相同,但他的解决方案并不适用于我:
所以用例。用户一个接一个地添加2条新记录:
用户查看网格中的一条记录
按"添加新记录"再次按钮
记录一个准备就绪。按'保存'。数据转到控制器而不是数据库。 在这一刻发生了一些事情,网格再次发送Ajax请求,记录一个数据给控制器。
用户更新网格并查看三条记录
" Alex | 10 |第一" (重复记录)ID = 1
"鲍勃| 20 |第二" ID = 2
" Alex | 10 |第一" ID = 1
他们建议返回一个ID以正确绑定\更新数据源与新记录。 我返回它(来自数据库的新ID与bouns实体一起响应)!这没有用。 只有当我用F5添加第一个记录和刷新页面之后再添加第二个记录一切正常。但如果添加另一个,第三个记录 - 问题再次出现
控制器中的代码:
[HttpPost]
public JsonResult Create(BonusDto bonusDto)
{
BonusAggregate bonus;
if (bonusDto.Amount <= 0)
throw new ArgumentOutOfRangeException("Amount should be more than 0");
if (bonusDto.EmployeeId <= 0)
throw new ArgumentNullException("You should specify an existing employee");
using (var dbContext = new DatabaseContext())
{
BonusesRepository = new BonusesRepository(dbContext);
var employeeRepository = new EmployeesRepository(dbContext);
bonus = new BonusFactory(employeeRepository).Create(bonusDto);
BonusesRepository.Save(bonus);
}
HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;
return Json(bonus); // try to return ID after bonus was saved
}
UI代码
// creates bonuses grid control
$("#bonusesGrid").kendoGrid({
dataSource: bonusesDataSource,
toolbar: ["create"],
editable: "inline",
columns: [
"BonusId",
"EmployeeId",
{
field: "EmployeeLastName",
editor: employeeAutocompletingEditor,
template: "#=EmployeeLastName#"
},
"Amount",
{
field: "Comment",
titel: "Comment",
editor: textareaEditor,
filterable: {
operators: {
number: {
contains: "Contains"
}
}
}
},
{
command: ["edit"],
title: " "
}
],
save: function(e) {
if (newValueEmployeeId !== undefined &&
newValueEmployeeLastName !== undefined &&
newValueEmployeeLastName !== "") {
setNewValueEmployeeIdAndLastName(newValueEmployeeId, newValueEmployeeLastName);
gridDataSource.model.EmployeeId = newValueEmployeeId; // it's a hack to bind model and autocomplete control
gridDataSource.model.EmployeeLastName = newValueEmployeeLastName;
} else {
gridDataSource.model.EmployeeId = currentValueEmployeeId;
gridDataSource.model.EmployeeLastName = currentValueEmployeeLastName;
}
},
edit: function(e) {
setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
},
cancel: function(e) {
setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
}
});
奖金数据来源:
// bind json result from /Bonuses/GetPagedJsonBonuses
var bonusesDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "@Url.Action("GetPagedJsonBonuses", "Bonuses")",
type : "GET",
contentType: "application/json",
dataType: "json",
cache: false
},
create: {
url: "@Url.Action("Create", "Bonuses")",
dataType: "json",
type: "POST"
},
parameterMap: function(options, operation) {
if (operation === "update" || operation === "create") {
// correct format for conversion
var d = new Date(options.Date);
options.Date = kendo.toString(d, dateFormat);
// updates the BonusDTO.EmployeeId with selected value
if (newValueEmployeeId !== undefined)
options.EmployeeId = newValueEmployeeId;
}
if(operation === "read") {
options.filter = setFormattedFilterDate(options.filter);
}
return options;
}
},
pageSize: 15,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
error: showErrorMessage,
schema: {
data: "Data", // PagedResponse.Data
total: "TotalCount", // PagedResponse.TotalCount
model: {
id: "BonusId", // Data
fields: {
EmployeeId: { type: "number" },
EmployeeLastName: {
type: "string",
editable: true,
nulable: false,
validation: { required: {message: "Employee's last name is required"}}
},
Date: {
type: "date",
editable: true,
nullable: false,
validation: {
required: { message: "Date is required to be set" }
}
},
Amount: {
type: "number",
editable: true,
nullable: false,
defaultValue: 1,
validation: {
required: { message: "Amount is required to be set" }
}
},
Comment: { type: "string", editable: true }
} // fields
} // model
}// schema
});
答案 0 :(得分:11)
我的代码中没有看到这个问题。但是我在创建和更新事件上有一个“完整”的事件处理程序,它刷新了网格 - 它可能对你有帮助:
dataSource: {
type: "jsonp",
transport: {
read: UrlBase + "getAll",
update: {
url: UrlBase + "Update",
dataType: "jsonp",
complete: function (e) {
$("#grid").data("kendoGrid").dataSource.read();
}
},
create: {
url: UrlBase + "create",
dataType: "jsonp",
complete: function (e) {
$("#grid").data("kendoGrid").dataSource.read();
}
},
destroy: {
url: UrlBase + "destroy",
dataType: "jsonp",
complete: function (e) {
$("#grid").data("kendoGrid").dataSource.read();
}
}
},
...
答案 1 :(得分:3)
是的,侮辱是正确的。你的&#34;创造&#34;操作结果从您的模型传递要保存到数据库的对象。让数据访问层中的INSERT返回数据库中新创建的密钥(&#34; ID&#34;)。现在使用此键设置&#34; ID&#34;您的模型上的字段传入操作结果,然后作为JSON传递回视图。现在网格应该知道它刚刚创建了这条记录,并且不需要再用它做任何事情。否则,模型对象返回&#34; ID&#34;字段设置为0,因此网格认为它仍然需要添加此记录。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Grid_Create([DataSourceRequest] DataSourceRequest request, MyObject obj)
{
if (obj != null && ModelState.IsValid)
{
obj.Id = _myService.Create(obj);
}
return Json(new[] { obj }.ToDataSourceResult(request, ModelState));
}
答案 2 :(得分:2)
如果在读取操作中未传递主键进行查看,则会发生此错误。
此致
答案 3 :(得分:2)
Quinton Bernhardt的完整事件的替代方案:将dataSource.read()绑定到kendo同步事件。
我使用的是剑道的C#MVC的html帮助器,它们不会暴露同步事件,因此我必须在设置网格后对其进行修改。
在窗口加载时:
var grid = $("#GridName").data("kendoGrid");
grid.dataSource.bind("sync", function () {
$("#GridName").data("kendoGrid").dataSource.read();
});
保存请求完成后,同步事件将触发。 dataSource.read()
从服务器获取最新信息,包括设置服务器端的ID。
答案 4 :(得分:2)
我有一个类似的问题,进行了各种试验但是通过以下试验确定了
<强> Jquery的强>
create: {
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: "../../ajax/ajaxGv.aspx/addstaff"
},
parameterMap: function (options, operation) {
if (operation == "create" && options.models) {
return JSON.stringify({ "oStaff": options.models });
}
<强> VB.Net 强>
'Adding Staff
<System.Web.Services.WebMethod()> _
Public Shared Sub addStaff(ByVal oStaff As Object)
Dim strJson As String = JsonConvert.SerializeObject(oStaff)
Dim lstStaff As List(Of Staff) = JsonConvert.DeserializeObject(Of List(Of Staff))(strJson)
Dim db As New LiveB2cDataContext
Try
db.Staff.InsertAllOnSubmit(lstStaff)
Next
db.SubmitChanges()
'Fix is that you need to return the objects you have added in the database back as json to kendo
strJson = JsonConvert.SerializeObject(lstStaff, Formatting.None)
WriteJson(strJson) ' Returning the objects added as json back to Kendo
Catch ex As Exception
ErrorLog(ex)
End Try
End Sub
Public Shared Sub WriteJson(strJson As String)
Try
HttpContext.Current.Response.Write(strJson)
HttpContext.Current.Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
HttpContext.Current.Response.SuppressContent = True
Catch ex As Exception
ErrorLog(ex)
End Try
End Sub
<强> Fix is that you need to return the objects you have added in the database back as json to kendo
强>
答案 5 :(得分:0)
我不确定这是否是您的问题的一部分,但是在您的DataSource的架构模型中,您指定ID是名为“BonusId”的字段,但该字段未在字段数组中指定。
答案 6 :(得分:0)
我遇到了类似的问题。
我修复了它,但确保模型中的id引用了一个字段: -
model: {
id: "Id",
fields: {
Id: { editable: false, type: "number" },
AnotherName: { editable: true, type: "string" },
AnotherId: { editable: true, type: "number" }
}
}
答案 7 :(得分:0)
这可能无法解决提问者的问题,但希望可以帮助有同样问题的人。
对于我们来说,这个问题是由JSON中返回的错误引起的。某些必需属性没有值,但与我们在网格中显示的数据无关。在网格中为这些属性提供默认值可以解决问题。
您可以使用Fiddler Web Debugging Tools查看返回的JSON。