我有一个带有kendo Grid的mvc应用程序
这里是视图代码
@using Domain.Agromilieu2.Wui.Resources.Bedrijfsgegevens.Views
@using Domain.Agromilieu2.Wui.Models.BeheerTeksten
@model TekstenViewModel.Main
@{
Layout = WebCore.Views.Layouts.Extended;
}
<h2>Teksten</h2>
@(Html.Kendo().Window()
.Name("alertWindow")
.Title("Status Message from Server")
.Draggable()
.Resizable()
.Width(400)
.Height(200)
.Modal(true)
.Visible(false)
.Actions(actions => actions.Close())
)
@Html.WebCore().Popup.CustomButtons("popupDemo", "Waarde", Html.Kendo().Editor().Name("waardeEditor").HtmlAttributes(new { @class = "editorStyle" }).Tools(tools => tools
.Clear()
.Bold().Italic().Underline().Strikethrough()
.JustifyLeft().JustifyCenter().JustifyRight().JustifyFull()
.InsertUnorderedList().InsertOrderedList()
.Outdent().Indent()
.CreateLink().Unlink()
.InsertImage()
.SubScript()
.SuperScript()
.TableEditing()
.ViewHtml()
.Formatting()
.FontName()
.FontSize()
.FontColor().BackColor()
).ToHtmlString(), new[]{new PopupButton("popupDemoAnnuleren", "Cancel", false),new PopupButton("popupDemoOk", "OK")})
<div class="infoPanel">
<div id='divSousMenu'>
<div>
<h2 class="zoekCriteria">ZOEKCRITERIA</h2>
<h4 class="resourceSet">Resource Set:</h4>
@(Html.Kendo().ComboBoxFor(model => model.Filter.userName)
.Name("resourcesSetComboBox")
.DataTextField("Naam")
.DataValueField("ID")
.Filter(FilterType.Contains)
.HtmlAttributes(new { @class = "comboStyle" })
.DataSource(source =>
{
source.Read(read =>
{
read.Action(MVC.BeheerTeksten.ActionNames.ResourceSetsIntoCombo_Read, MVC.BeheerTeksten.Name)
.Data("onAdditionalData");
})
.ServerFiltering(true);
})
.AutoBind(false)
)
</div>
<div class='gewijzigdItem'>
<h4 class="gewijzigdDoor">Gewijzigd door:</h4>
@(Html.Kendo().ComboBox()
.Name("usersSetComboBox")
.DataTextField("DisplayName")
.DataValueField("UserName")
.Filter(FilterType.Contains)
.HtmlAttributes(new { @class = "comboStyle" })
.DataSource(source =>
{
source.Read(read =>
{
read.Action(MVC.BeheerTeksten.ActionNames.GebruikersIntoCombo_Read, MVC.BeheerTeksten.Name)
.Data("onAdditionalData");
})
.ServerFiltering(true);
})
.AutoBind(false)
)
</div>
<div class='vanItem'>
<h4 class="van">Van:</h4>
@(Html.Kendo().DateTimePicker()
.Name("vanTimepicker")
.Max(DateTime.Today)
.Events(events => events.Change("onVanTimeChange"))
.HtmlAttributes(new { @class = "dateTimePickerStyle;" })
)
</div>
<div class='totItem'>
<h4 class="tot">Tot:</h4>
@(Html.Kendo().DateTimePicker()
.Name("totTimepicker")
.Max(DateTime.Today)
.Events(events => events.Change("onTotTimeChange"))
.HtmlAttributes(new { @class = "dateTimePickerStyle;" })
)
</div>
</div>
</div>
<div class="separator"></div>
@*<hr />*@
<div class="zoekResultatLine">
<h2 class="zoekResultat">ZOEKRESULTAAT</h2>
</div>
@(Html.Kendo().Grid<TekstenViewModel.Tekst>()
.Name("Grid")
.Columns(columns =>
{
columns.Template(@<text></text>).ClientTemplate("<input type='checkbox'/>").Width(10).Hidden(!Model.Administrator);
columns.Bound(product => product.RESOURCE_SET_NAAM).Width(125).ClientTemplate("#= RESOURCE_SET_NAAM#");
columns.Bound(product => product.Naam).Width(125).ClientTemplate("#= Naam#");
columns.Bound(product => product.Waarde).Width(125).ClientTemplate("<div id='editorDiv'><div class='input'>#=Waarde#</div><div class='editor'>" +
Html.WebCore().LinkButton(type: ButtonType.MeerActies, htmlAttributes: new { onclick = "openPopupDemo('#: Waarde #', '#: ID #', 'Waarde')" }));
columns.Bound(product => product.Opmerking).Width(250).ClientTemplate("<div id='editorDiv'><div class='input'>#=Opmerking#</div><div class='editor'>" +
Html.WebCore().LinkButton(type: ButtonType.MeerActies, htmlAttributes: new { onclick = "openPopupDemo('#: Opmerking #', '#: ID #', 'Opmerking')" }));
columns.Template(@<text></text>).ClientTemplate("<div id='deleteDiv'><div class='delete'><a class=\"delete iconBtn\" onclick=\"deleteResourceItem(#: ID #, '#: Naam #')\"></a></div></div>").Width(10).Hidden(!Model.Administrator);
})
.Pageable()
.Sortable()
.Filterable()
.Events(events => events.Edit("onCellEdit").DataBinding("onDataBinding"))
.Groupable()
.Navigatable()
.Editable(editable => editable.Mode(GridEditMode.InCell).DisplayDeleteConfirmation(false))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.Events(e => e.Error("error_handler"))
.Model(model =>
{
model.Id(product => product.ID);
model.Field(product => product.Naam).Editable(Model.Administrator);
model.Field(product => product.Opmerking).Editable(Model.Administrator);
model.Field(product => product.Waarde).Editable(!Model.ReadOnly);
model.Field(product => product.RESOURCE_SET_ID).DefaultValue(Model.SetID);
model.Field(product => product.Type).DefaultValue(Domain.Agromilieu2.Common.Objects.Entities.Resources.ResourceType.GLOBAL_RESOURCES);
model.Field(product => product.Taal).DefaultValue(Domain.Agromilieu2.Common.Agromilieu2Constants.Resources.DEFAULT_TAAL_CODE);
})
.Create(create => create.Action(MVC.BeheerTeksten.ActionNames.ResourceItems_Create, MVC.BeheerTeksten.Name))
.Read(read => read.Action(MVC.BeheerTeksten.ActionNames.ResourceItems_Read, MVC.BeheerTeksten.Name, new { setID = Model.SetID }).Data("onReadAdditionalData"))
.Update(update => update.Action(MVC.BeheerTeksten.ActionNames.ResourceItems_Update, MVC.BeheerTeksten.Name))
.Destroy(destroy => destroy.Action(MVC.BeheerTeksten.ActionNames.ResourceItems_Delete, MVC.BeheerTeksten.Name))
)
)
@Html.WebCore().Popup.Remove("confirmResourceItemPopup", "Verwijderen resource item", "")
@section Scripts
{
@Scripts.Render(Links.Bundles.Scripts.BeheerTeksten.Teksten)
<script type="text/javascript">
function onCellEdit(e) {
var grid = $("#Grid").data("kendoGrid");
var row = $(e.container).closest("tr");
var colIdx = $("td", row).index($(e.container));
var columname = e.sender.columns[colIdx].field;
e.container.find("[name='" + columname + "']").toggleClass('editInput');
}
function onDataBinding(e) {
var grid = $("#Grid").data("kendoGrid");
if ($("#resourcesSetComboBox").data("kendoComboBox").value() == "")
grid.showColumn(1);
else
grid.hideColumn(1);
}
function onVanTimeChange() {
var vanTimeValue = kendo.toString($("#vanTimepicker").data("kendoDateTimePicker").value(), "dd/MM/yyyy HH:mm:ss.ffff")
$("#totTimepicker").data("kendoDateTimePicker").min(vanTimeValue);
}
function onTotTimeChange() {
var totTimeValue = kendo.toString($("#totTimepicker").data("kendoDateTimePicker").value(), "dd/MM/yyyy HH:mm:ss.ffff")
$("#vanTimepicker").data("kendoDateTimePicker").max(totTimeValue);
}
function onAdditionalData() {
var code = window.location.pathname.split('/');
return {
toepassingsCode: code[5]
};
}
function onReadAdditionalData() {
var resourceID = $.urlParam('setID');
if (resourceID) {
$("#resourcesSetComboBox").data("kendoComboBox").value(resourceID);
$("#resourcesSetComboBox").data("kendoComboBox").enable(false);
}
else
resourceID = $("#resourcesSetComboBox").data("kendoComboBox").value();
var user = $.urlParam('userName');
if (user) {
$("#usersSetComboBox").data("kendoComboBox").value(user);
$("#usersSetComboBox").data("kendoComboBox").enable(false);
}
else
user = $("#usersSetComboBox").data("kendoComboBox").value();
var vanTimeValue = $.urlParam('vanTime');
if (vanTimeValue) {
$("#vanTimepicker").data("kendoDateTimePicker").value(new Date(Date.parse(vanTimeValue, "dd/MM/yyyy HH:mm:ss")));
$("#vanTimepicker").data("kendoDateTimePicker").enable(false);
}
else
var vanTimeValue = kendo.toString($("#vanTimepicker").data("kendoDateTimePicker").value(), "dd/MM/yyyy HH:mm:ss.ffff")
var totTimeValue = $.urlParam('totTime');
if (totTimeValue) {
$("#totTimepicker").data("kendoDateTimePicker").value(totTimeValue);
$("#totTimepicker").data("kendoDateTimePicker").enable(false);
}
else
var totTimeValue = kendo.toString($("#totTimepicker").data("kendoDateTimePicker").value(), "dd/MM/yyyy HH:mm:ss.ffff")
return {
setID: resourceID,
userName: user,
vanTime: vanTimeValue,
totTime: totTimeValue
};
}
$.urlParam = function (name) {
var enc = decodeURI(window.location.href);
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(enc);
if (results != null)
return results[1];
}
function deleteResourceItem(resourceItemID, resourceItemName) {
domain.Agromilieu2.Wui.BeheerTeksten.Teksten.deleteResourceItem(resourceItemID, resourceItemName);
}
var selectedGridRowID = 0;
var selectedGridColumnName;
function openPopupDemo(gridCellContent, gridIdentifier, columnIdentifier) {
var editor = $("#waardeEditor").data("kendoEditor")
if (('@Html.Raw(Json.Encode(Model.ReadOnly))' == "false" && '@Html.Raw(Json.Encode(Model.Administrator))' == "false" && columnIdentifier != "Waarde") || '@Html.Raw(Json.Encode(Model.ReadOnly))' == "true")
editor.body.contentEditable = false;
else
editor.body.contentEditable = true;
editor.value(htmlDecode(gridCellContent));
domain.WebCore.popup.show("popupDemo");
selectedGridRowID = gridIdentifier;
selectedGridColumnName = columnIdentifier;
};
function htmlDecode(value) {
return $('<div/>').html(value).text();
}
function htmlEncode(value) {
return $('<div/>').text(value).html();
}
function htmlEscape(str) {
return String(str)
.replace(/"/g, '"')
.replace(/'/g, ''')
}
domain.WebCore.popup.configure("popupDemo")
.click(function (b) {
var grid = $("#Grid").data("kendoGrid");
var editor = $("#waardeEditor").data("kendoEditor")
var parentItem = grid.dataSource.get(selectedGridRowID);
parentItem.set(selectedGridColumnName, htmlEscape(htmlEncode(editor.value())));
});
function showAlertWindow(message) {
var alertWindow = $('#alertWindow').data('kendoWindow');
alertWindow.content(message);
alertWindow.refresh();
alertWindow.center();
alertWindow.open();
}
function error_handler(e) {
if (e.errors) {
var message = "";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
showAlertWindow(message);
}
}
$(function () {
domain.Agromilieu2.Wui.BeheerTeksten.Teksten.init(
{
deleteResourceItemUrl: "@Url.Action(MVC.BeheerTeksten.ResourceItems_Delete())",
deleteResourceItemMessage: "<p>Bent u zeker dat u '{0}' wil verwijderen?</p><p><strong>Opgelet!</strong><br>Hierbij worden ook alle teksten verbonden aan deze resource set verwijderd.</p>",
ResourceItems_ReadUrl: "@Url.Action(MVC.BeheerTeksten.ResourceItems_Read())"
});
});
</script>
}
这是我的控制器代码。
// GET /Agromilieu2/Beheer/Teksten/Teksten
[HttpGet]
[Domain.BasisArchitectuur.Framework.MVC.ActionFilters.MenuItem("Teksten")]
[IsAgromilieuActieAllowed(ActieClaims.TekstenRaadpleger)]
public virtual ActionResult Teksten(string toepassingsCode = null, long? setID = null, string taalCode = null, string resourceType = null, string user = null)
{
bool admin = SecurityHelper.IsActieAllowed(ActieClaims.TekstenAdmin);
LayoutService.SubTitle = DetailResources.TITEL_Header;
if (admin)
{
LayoutService.SubmitActions = new List<LinkButton>
{
new LinkButton { ButtonType = ButtonType.Toevoegen, CssClass = "myToevoegenButton", IsDisabled = setID == null, ClientId = "teste" },
new LinkButton { ButtonType = ButtonType.Delete, CssClass = "myVerwijderenButton" },
new LinkButton { ButtonType = ButtonType.Zoeken, CssClass = "primair myZoekenButton" }
};
}
else
{
LayoutService.SubmitActions = new List<LinkButton>
{
new LinkButton { ButtonType = ButtonType.Zoeken, CssClass = "primair myZoekenButton" }
};
}
if (string.IsNullOrEmpty(toepassingsCode))
{
return RedirectToAction(MVC.BeheerTeksten.Toepassingen());
}
else
{
if (!string.IsNullOrEmpty(resourceType) && resourceType == ResourceType.REFE_RESOURCES)
{
return RedirectToAction(MVC.BeheerTeksten.RefeTeksten(toepassingsCode, setID, taalCode));
}
else
{
if (string.IsNullOrEmpty(taalCode))
{
taalCode = Agromilieu2Constants.Resources.DEFAULT_TAAL_CODE;
}
LayoutService.SubTitle = string.Format("Beheer Teksten - {0}",
BL.Resources.Resources.GetToepassingen().First(x => x.Code == toepassingsCode).Omschrijving);
TekstenViewModel.Main model = new TekstenViewModel.Main
{
DefaultTaal = Agromilieu2Constants.Resources.DEFAULT_TAAL_CODE,
Filter = new TekstenViewModel.ZoekCriteria
{
ResourceSet_ID = setID,
Taal = taalCode,
userName = user
},
ToepassingsCode = toepassingsCode,
SetID = setID,
ReadOnly = !(SecurityHelper.IsActieAllowed(ActieClaims.TekstenAdmin) || SecurityHelper.IsActieAllowed(ActieClaims.TekstenBeheer)),
Administrator = SecurityHelper.IsActieAllowed(ActieClaims.TekstenAdmin)
};
return View(model);
}
}
}
[HttpPost]
[Domain.BasisArchitectuur.Framework.MVC.ActionFilters.MenuItem("Teksten")]
[IsAgromilieuActieAllowed(ActieClaims.TekstenRaadpleger)]
public virtual ActionResult ResourceItems_Read([DataSourceRequest]DataSourceRequest request, long? setID, string userName, string vanTime, string totTime, string taalCode = Agromilieu2Constants.Resources.DEFAULT_TAAL_CODE)
{
DateTime? newVanTime = null;
DateTime? newTotTime = null;
if(!String.IsNullOrEmpty(vanTime))
newVanTime = DateTime.Parse(vanTime);
if (!String.IsNullOrEmpty(totTime))
newTotTime = DateTime.Parse(totTime);
TekstenViewModel.ZoekCriteria searchCriteria = new TekstenViewModel.ZoekCriteria
{
ResourceSet_ID = setID,
type_Code = ResourceType.GLOBAL_RESOURCES,
Taal = taalCode,
userName = userName,
vanTime = newVanTime,
totTime = newTotTime
};
List<TekstenViewModel.Tekst> resourceItemsList = new List<Models.BeheerTeksten.TekstenViewModel.Tekst>();
resourceItemsList = GetResourceItemsList(searchCriteria);
return Json(resourceItemsList.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
[AcceptVerbs(HttpVerbs.Post)]
[Domain.BasisArchitectuur.Framework.MVC.ActionFilters.MenuItem("Teksten")]
[IsAgromilieuActieAllowed(ActieClaims.TekstenBeheren)]
public virtual ActionResult ResourceItems_Create([DataSourceRequest]DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<TekstenViewModel.Tekst> resourceItems)
{
List<ResourceItemDto> entities = new List<ResourceItemDto>();
if (ModelState.IsValid)
{
try
{
using (IProxy<IResourceService> proxy = _proxyFactory.Create<IResourceService>())
{
foreach (TekstenViewModel.Tekst tekstenViewModel in resourceItems)
{
ResourceItemDto resourceItem = new ResourceItemDto
{
ResourceItem_ID = tekstenViewModel.ID,
ResourceSet_ID = tekstenViewModel.RESOURCE_SET_ID,
Naam = HttpUtility.HtmlDecode(tekstenViewModel.Naam),
Opmerking = HttpUtility.HtmlDecode(tekstenViewModel.Opmerking),
Waarde = HttpUtility.HtmlDecode(tekstenViewModel.Waarde),
Type_Code = tekstenViewModel.Type,
Taal_Code = tekstenViewModel.Taal,
ResourceWaarde_ID = tekstenViewModel.WAARDE_ID
};
entities.Add(resourceItem);
}
proxy.Client.CheckIfNameExists(entities);
proxy.Client.AddOrUpdateResourceItem(entities.AsEnumerable());
}
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, ex.Message);
}
}
else
{
var errMsg = ModelState.Values
.Where(x => x.Errors.Count >= 1)
.Aggregate("Model State Errors: ", (current, err) => current + err.Errors.Select(x => x.ErrorMessage));
ModelState.AddModelError(string.Empty, errMsg);
}
//ModelState.AddModelError("Naam", );
//resourceItems = GetResourceItemsList(new TekstenViewModel.ZoekCriteria { Taal = resourceItems.FirstOrDefault().Taal, ResourceSet_ID = resourceItems.FirstOrDefault().RESOURCE_SET_ID });
return Json(entities.ToDataSourceResult(request, ModelState));
}
[AcceptVerbs(HttpVerbs.Post)]
[Domain.BasisArchitectuur.Framework.MVC.ActionFilters.MenuItem("Teksten")]
[IsAgromilieuActieAllowed(ActieClaims.TekstenBeheren)]
public virtual ActionResult ResourceItems_Update([DataSourceRequest]DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<TekstenViewModel.Tekst> resourceItems)
{
List<ResourceItemDto> entities = new List<ResourceItemDto>();
if (ModelState.IsValid)
{
try
{
using (IProxy<IResourceService> proxy = _proxyFactory.Create<IResourceService>())
{
foreach (TekstenViewModel.Tekst tekstenViewModel in resourceItems)
{
ResourceItemDto resourceItem = new ResourceItemDto
{
ResourceItem_ID = tekstenViewModel.ID,
ResourceSet_ID = tekstenViewModel.RESOURCE_SET_ID,
Naam = HttpUtility.HtmlDecode(tekstenViewModel.Naam),
Opmerking = HttpUtility.HtmlDecode(tekstenViewModel.Opmerking),
Waarde = HttpUtility.HtmlDecode(tekstenViewModel.Waarde),
Type_Code = tekstenViewModel.Type,
Taal_Code = tekstenViewModel.Taal,
ResourceWaarde_ID = tekstenViewModel.WAARDE_ID
};
entities.Add(resourceItem);
}
proxy.Client.AddOrUpdateResourceItem(entities.AsEnumerable());
}
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, ex.Message);
}
}
else
{
var errMsg = ModelState.Values
.Where(x => x.Errors.Count >= 1)
.Aggregate("Model State Errors: ", (current, err) => current + err.Errors.Select(x => x.ErrorMessage));
ModelState.AddModelError(string.Empty, errMsg);
}
return Json(resourceItems.ToDataSourceResult(request, ModelState));
}
[HttpDelete]
[IsAgromilieuActieAllowed(ActieClaims.TekstenBeheren)]
public virtual ActionResult ResourceItems_Delete(long? id)
{
using (IProxy<IResourceService> proxy = _proxyFactory.Create<IResourceService>())
{
proxy.Client.DeleteResourceItemRecursively(id);
}
return Content(CoreService.LastMainScreenUrl ?? MvcConfig.DefaultStartupUrl);
}
[HttpPost]
[IsAgromilieuActieAllowed(ActieClaims.TekstenBeheren)]
public virtual ActionResult ResourceItems_Delete( [Bind(Prefix="models")] List<TekstenViewModel.Tekst> resourceItems)
{
using (IProxy<IResourceService> proxy = _proxyFactory.Create<IResourceService>())
{
foreach(TekstenViewModel.Tekst resourceItem in resourceItems )
{
proxy.Client.DeleteResourceItemRecursively(resourceItem.ID);
}
}
return Content(CoreService.LastMainScreenUrl ?? MvcConfig.DefaultStartupUrl);
}
[HttpGet]
[IsAgromilieuActieAllowed(ActieClaims.TekstenRaadpleger)]
public virtual JsonResult ResourceSetsIntoCombo_Read(string toepassingsCode)
{
ResourceWcfDataServiceProxy proxy = DependencyResolver.Current.GetService<ResourceWcfDataServiceProxy>();
IEnumerable<ResourceSetsViewModel.ResourceSet> sets =
Enumerable.Repeat(new ResourceSetsViewModel.ResourceSet { Naam = "Maak een selectie" }, 1).Union(proxy.ResourceSetSet
.Where(s => s.ToepassingsCode == toepassingsCode)
.Select(s => new
{
ID = s.ID,
Naam = s.Naam,
Opmerking = s.Opmerking,
Type = s.Type.Code
}).ToList()
.Select(s => new ResourceSetsViewModel.ResourceSet
{
ID = s.ID,
Naam = s.Naam,
Opmerking = s.Opmerking,
Type = s.Type
}));
return Json(sets.ToList(), JsonRequestBehavior.AllowGet);
}
[HttpGet]
[IsAgromilieuActieAllowed(ActieClaims.TekstenRaadpleger)]
public virtual JsonResult GebruikersIntoCombo_Read(string toepassingsCode)
{
IEnumerable<TekstenViewModel.UserInfo> journalingUsers;
using (IProxy<IResourceService> proxy = _proxyFactory.Create<IResourceService>())
{
journalingUsers = Enumerable.Repeat(new TekstenViewModel.UserInfo { UserName = null, DisplayName = "Maak een selectie" }, 1)
.Union(proxy.Client.GetUsers(toepassingsCode).Select(x => new TekstenViewModel.UserInfo { UserName = x, DisplayName = x }));
}
return Json(journalingUsers.ToList(), JsonRequestBehavior.AllowGet);
}
当我更新,阅读或删除时,一切正常。当我创建时,就像我没有在网格中找回正确的数据一样。
我的意思是,我创建一个新记录并按Save,它会调用网格的savechanges事件。到目前为止一切都那么好,但如果我再次按Save,它会再次调用savechanges事件,我会收到此错误。
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
这是在创建新记录之前的网格图片。
这里是插入新记录后的网格图片
第一张唱片应该是最后一张。不知道为什么会这样。