Hello...
I have a grid on a razor page that shows related data to the main model. The grid has the usual CRUD operation buttons and there are corresponding post code in the .CS file. The anti-forgery token is configured and sent with each call back to the server. The grid is using in-line editing, so nothing custom at all. I have a Read operation defined, but because I am binding from the server it never gets called (just there for consistency). This is the grid in the CSHTML page:
@(Html.Kendo().Grid<SettlementHistoryModel>(Model.CoDefendantList)
.Name("coDefendantGrid")
.Mobile(MobileMode.Phone)
.DataSource(ds => ds
.Ajax()
.PageSize(30)
.Events(ev => ev.Error("errorHandler"))
.Model(m =>
{
m.Id(cod => cod.SettlementId);
m.Field(f => f.SettlementId).Editable(false);
})
.Batch(false)
.Create(c => c.Url("/CaseEdit?handler=NewCoDefendant").Data("forgeryToken"))
.Read(r => r.Url("/CaseEdit?handler=ReadCoDefendant").Data("forgeryToken"))
.Update(u => u.Url("/CaseEdit?handler=UpdateCoDefendant").Data("forgeryToken"))
.Destroy(d => d.Url("/CaseEdit?handler=DeleteCoDefendant").Data("forgeryToken"))
.ServerOperation(false)
)
.Pageable()
.Sortable(s => s
.AllowUnsort(true)
.SortMode(GridSortMode.Mixed)
.ShowIndexes(true)
)
.ToolBar(tb => tb.Create())
.Editable(ed => ed.Mode(GridEditMode.InLine))
.Scrollable(s => s.Enabled(true).Height("auto"))
.Columns(c =>
{
c.Command(c =>
{
c.Edit();
c.Destroy();
}).Width("15%").HtmlAttributes(new { style = "vertical-align: top;"}).Title("Actions");
c.Bound(res => res.SettlementId).Title("ID").Width("5%");
c.Bound(res => res.CaseId).Title("Case").Width("5%");
c.Bound(res => res.Codefendant).Title("Co-Defendant").Width("15%");
c.Bound(res => res.Settlement).Title("Settlement").Format("{0:c2}").Width("10%");
c.Bound(res => res.SettlementDate).Title("Settlement Date").Format("{0:MM/dd/yyyy}").Width("10%");
c.Bound(res => res.Comments).Title("Comments").Encoded(false);
})
.ColumnMenu(m => m
.ComponentType("modern")
.Columns(cm => cm.Sort("asc")))
.Reorderable(r => r.Columns(true))
.Resizable(rs => rs.Columns(true)))
Ok, so data populates in the grid with no problem and the appropriate Add, Edit and Delete buttons appear where they should. The appropriate post method is called. Here, for example, is the Update method:
public JsonResult OnPostUpdateCoDefendant(SettlementHistoryModel settlement, [DataSourceRequest] DataSourceRequest request)
{
// Check for a valid object
if (settlement != null)
{
//_context.SettlementHistories.Update(settlement);
//_context.SaveChanges();
}
// And return the JSON for the object
return new JsonResult(new[] { settlement }.ToDataSourceResult(request, ModelState));
}
The problem? When this method is hit, the SettlementHistoryModel object is not null, but all of the properties of the singular object ARE null (except the SettlementId, which is 0). It doesn't matter how the grid gets the data (server binding or Read action), which order the items are in the method signature, etc. The method is called, but ultimately the operation will fail because there is nothing in the SettlementHistoryModel object.
I've downloaded the grid demo and that seems to work. My code is pretty much exactly the same as the demo code, yet there is no way I have tried that gets my code working.
What am I missing?
Additional information:
I think the object is not making it to the server because the main bound object (the parent table where SettlementHistory described above is a related table) is not valid. I didn't notice this because I stopped on a break point on the server side when I saw the object was null. Going back to the browser triggered the onError JS code which said 5 required fields in that model were not supplied.
Weird thing is that the grid sits outside of the form where this other bound object is located. With the SettlementHistory object explicitly part of the method signature and the place where the grid lives, I would have expected the main model state would not play into this at all. Apparently ASP.NET thinks otherwise.