I have a pure JS grid I was using with an asp.net forms backend (.ashx). It has been working fine for six months. I am trying to convert it to an MVC controller for the backend now, but having no luck:
My material entry controller for the Create function looks like this:
I know the logic inside create isn't right. But the problem is that the 'materials' parameter is empty when the Create method is called. You can see that the form data seems to be being sent correctly in chrome's Netowork tab, by looking at the attached file.
Any ideas what I am doing wrong?
function MaterialsGrid(ticket_ID, grid_id, is_editable, default_billable) { var self = this; self.ticket_ID = ticket_ID; self.GRID_ID = '#' + grid_id; self.HANDLER_URL = "/MaterialEntry"; self.IS_EDITABLE = is_editable; self.DEFAULT_BILLABLE = default_billable; self.material_source = new kendo.data.DataSource({ batch: true, schema: { model: { id: "MaterialEntryID", fields: { MaterialEntryID: { type: "string" }, TicketID: { type: "string" }, ItemID: { type: "number", defaultValue: 0 }, ItemName: { type: "string", defaultValue: GridCommon.emptyText }, Description: { type: "string" }, Quantity: { type: "number", defaultValue: 0, validation: { required: true, min: 0 } }, Rate: { type: "number", defaultValue: 0 }, Total: { type: "number", defaultValue: 0 }, Billable: { type: "boolean", defaultValue: self.DEFAULT_BILLABLE }, }, } }, transport: { read: { url: self.HANDLER_URL + "/Read", dataType: "json", type: "GET", cache: false, }, update: { url: self.HANDLER_URL + "/Update", dataType: "json", type: "PUT", }, destroy: { url: self.HANDLER_URL + "/Destroy", dataType: "json", type: "POST", }, create: { url: self.HANDLER_URL + "/Create", dataType: "json", type: "POST", }, parameterMap: function (options, operation) { if (operation === "read") { return { ticketID: self.ticket_ID }; } if (operation === "read") { return { ticketID: self.ticket_ID }; } else if (options.models) { return { materials: kendo.stringify(options.models), ticketID: self.ticket_ID }; } } }, error: GridCommon.showCallBackError }); self.items_src = new kendo.data.DataSource({ transport: { read: { url: self.HANDLER_URL + "/GetItems", dataType: "json", type: "GET" } }, error: GridCommon.showCallBackError }); self.itemDropDownEditor = function (container, options) { $('<input required data-text-field="ExtendedItemName" data-value-field="ItemName" data-bind="value:' + options.field + '"/>') .appendTo(container) .kendoDropDownList({ autoBind: false, optionLabel: { ExtendedItemName: GridCommon.emptyText, ItemID: 0 }, dataSource: self.items_src, change: function (e) { options.model.set('ItemID', e.sender.dataItem().ItemID); } }); } self.updateTotal = function (e) { var r = e.values.Rate ? e.values.Rate : e.model.Rate; var q = e.values.Quantity ? e.values.Quantity : e.model.Quantity; e.model.set('Total', q * r); } self.init = function () { var tools = null; var row_commands = null; if (self.IS_EDITABLE) { tools = [ { name: "save", text: "Save" }, { name: "cancel", text: "Cancel" }, { name: "create", text: "Add" }, { template: GridCommon.toggleBillableTemplate(self.GRID_ID) } ]; row_commands = [{ name: "destroy", template: '<a href="##" class="k-grid-delete"><img img src="/Content/images/icons/delete.png" /></a>' }] } else { $(self.GRID_ID).addClass('readonly'); } $(self.GRID_ID).kendoGrid({ toolbar: tools, save: self.updateTotal, columns: [ { field: "ItemName", title: "Item Type", editor: self.itemDropDownEditor }, { field: "Description" }, { field: "Quantity", title: "QTY", width: 65, editor: GridCommon.numberEditor }, { field: "Rate", title: "Price", format: "{0:c}", width: 90, editor: GridCommon.numberEditor }, { field: "Total", editor: GridCommon.notEditable, format: "{0:c}", width: 95 }, { field: "Billable", template: '#= GridCommon.getBillableText(Billable) #', width: 100}, { command: row_commands, width: 40 } ], pageable: false, scrollable: true, editable: self.IS_EDITABLE, navigatable: true, sortable: true, batch: true, dataSource: self.material_source, saveChanges: GridCommon.saveAll }); }}@model Guid<div class="grid-wrapper"> <div id="materials-data" class="grid-global-save"> <!-- grid will appear here --> </div></div><script type="text/javascript"> var mat_grid = new MaterialsGrid('@Model', 'materials-data', true, true); $(document).ready(mat_grid.init);</script>[AcceptVerbs(HttpVerbs.Post)]public JsonResult Create([DataSourceRequest] DataSourceRequest request, IEnumerable<TempVM> materials, string ticketId){ ModelState.Remove("MaterialEntryId"); ModelState.Remove("Id"); return Json("");}public class TempVM{ public string MaterialEntryID { get; set; } public string TicketID { get; set; } public int ItemID { get; set; } public string Description { get; set; }}I know the logic inside create isn't right. But the problem is that the 'materials' parameter is empty when the Create method is called. You can see that the form data seems to be being sent correctly in chrome's Netowork tab, by looking at the attached file.
Any ideas what I am doing wrong?