This is a migrated thread and some comments may be shown as answers.

Grid Create & Update sending malformed JSON to server

5 Answers 70 Views
This is a migrated thread and some comments may be shown as answers.
Bob
Top achievements
Rank 1
Bob asked on 06 Dec 2013, 10:42 PM
This means my model is not binding and the operations are not working.

The read method works just fine, but that is it....  For Example, my Destroy Method:

CONTROLLER:
     public ActionResult Memo_Delete(MemoModel memo)
        {
            using (var context = new eEntities.eWJB())
            {
                Note _note = context.Notes.First(i => i.nMemoID == memo.memoID);
                context.Notes.Remove(_note);
                context.SaveChanges();
            }
            return Json(new[] { memo }.ToDataSourceResult(request, ModelState));
        }

The JS Below sends the following malformed JSON to the Controller:  It looks like Query Parameters / Not JSON:  

Any Suggestions?  I have tried the parameter mapping with no luck.

clientID=8&memoID=2&memoTime=Sat+May+08+2004+13%3A05%3A00+GMT-0700+(Pacific+Daylight+Time)&subject=General+Notes&memo=%24200+Appraisal+%230403053&initials=MM&code=4&eyesOnly=false&sticky=false

JS for the GRID:

    jQuery("#grid2").kendoGrid(
         {
             columns: [
               { "title": "Pin", "width": "30px", "field": "sticky", "filterable": {}, "encoded": true, "editor": null },
               { "title": "Private", "width": "30px", "field": "eyesOnly", "filterable": {}, "encoded": true, "editor": null },
               { "title": "Date", "width": "90px", "field": "memoTime", "format": "{0:dd/MM/yyyy}", "filterable": {}, "encoded": true, "editor": null },
               { "title": "Subject", "width": "125px", "field": "subject", "filterable": {}, "encoded": true, "editor": null },
               { "title": "Note", "width": "250px", "encoded": false, "field": "memo", "filterable": {}, "editor": null },
               { "title": "Initials", "width": "30px", "field": "initials", "filterable": {}, "encoded": true, "editor": null },
               {
                   "width": "172px", "command": [
                     { "name": "edit", "buttonType": "ImageAndText", "text": "Edit" }, { "name": "destroy", "buttonType": "ImageAndText", "text": "Delete" }]
               }],
             pageable: { "refresh": true, "pageSizes": [5, 10, 20], "buttonCount": 5 },
             sortable: true,
             selectable: "Single, Row",
             resizable: true,
             scrollable: false,
             editable: { "confirmation": "Are you sure you want to delete this record?", "mode": "popup", "template": "\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"clientID\"\u003eclientID\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"text-box single-line\" data-val=\"true\" data-val-number=\"The field clientID must be a number.\" data-val-required=\"The clientID field is required.\" id=\"clientID\" name=\"clientID\" type=\"number\" value=\"0\" /\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"clientID\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"memoID\"\u003ememoID\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"text-box single-line\" data-val=\"true\" data-val-number=\"The field memoID must be a number.\" data-val-required=\"The memoID field is required.\" id=\"memoID\" name=\"memoID\" type=\"number\" value=\"0\" /\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"memoID\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"memoTime\"\u003ememoTime\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput data-val=\"true\" data-val-date=\"The field memoTime must be a date.\" id=\"memoTime\" name=\"memoTime\" type=\"datetime\" /\u003e\u003cscript\u003e\tjQuery(function(){jQuery(\"\\\\\\#memoTime\").kendoDateTimePicker({\"format\":\"M/d/yyyy h:mm tt\",\"min\":new Date(1900,0,1,0,0,0,0),\"max\":new Date(2099,11,31,0,0,0,0),\"interval\":30});});\u003c\\/script\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"memoTime\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"subject\"\u003esubject\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" data-val=\"true\" data-val-required=\"The subject field is required.\" id=\"subject\" name=\"subject\" placeholder=\"\" type=\"text\" value=\"\" /\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"subject\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"memo\"\u003ememo\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" data-val=\"true\" data-val-required=\"The memo field is required.\" id=\"memo\" name=\"memo\" placeholder=\"\" type=\"text\" value=\"\" /\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"memo\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"initials\"\u003einitials\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" id=\"initials\" name=\"initials\" placeholder=\"\" type=\"text\" value=\"\" /\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"initials\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"code\"\u003ecode\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" data-val=\"true\" data-val-number=\"The field code must be a number.\" id=\"code\" name=\"code\" placeholder=\"\" type=\"text\" value=\"\" /\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"code\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"eyesOnly\"\u003eeyesOnly\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" id=\"eyesOnly\" name=\"eyesOnly\" placeholder=\"\" type=\"text\" value=\"\" /\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"eyesOnly\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"sticky\"\u003esticky\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cselect class=\"list-box tri-state\" id=\"sticky\" name=\"sticky\"\u003e\u003coption selected=\"selected\" value=\"\"\u003eNot Set\u003c/option\u003e\u003coption value=\"true\"\u003eTrue\u003c/option\u003e\u003coption value=\"false\"\u003eFalse\u003c/option\u003e\u003c/select\u003e \u003cspan class=\"field-validation-valid\" data-valmsg-for=\"sticky\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e", "window": { "title": "Edit", "modal": true, "draggable": true, "resizable": false }, "create": true, "update": true, "destroy": true }, "toolbar": { "command": [{ "name": null, "buttonType": "ImageAndText", "text": "Add new record" }] },
             dataSource: {
                 transport: {
                     prefix: "",
                     read: { url: "/Memo/Memos_Read"},
                     update: { url: "/Memo/Memo_Update", dataType: "json", contentType: "application/json", type: "POST" },
                     create: { url: "/Memo/Memo_Add", dataType: "json", contentType: "application/json", type: "POST" },
                     destroy: { url: "/Memo/Memo_Delete", dataType: "json", contentType: "application/json", type: "POST" }
                 },
                 parameterMap: function (options, operation) {
                     if (operation !== "read" && options.models) {
                         return {models: kendo.stringify(options.models)};
                     }
                     return options; // <-- added this line

                 
             },
                 pageSize: 10, "page": 1, "total": 0, "type": "aspnetmvc-ajax", "error": error_handler,
                 schema: {
                     data: "Data", "total": "Total", "errors": "Errors",
                     model: {
                         "id": "memoID", "fields":
                             {
                                 "clientID": { "type": "number" },
                                 "memoID": { "type": "number" },
                                 "memoTime": { "type": "date", "defaultValue": null },
                                 "subject": { "type": "string" },
                                 "memo": { "type": "string" },
                                 "initials": { "type": "string" },
                                 "code": { "type": "number", "defaultValue": null },
                                 "eyesOnly": { "type": "boolean", "defaultValue": null },
                                 "sticky": { "type": "boolean", "defaultValue": null }
                             }
                     }
                 }
             }
         });
   });

5 Answers, 1 is accepted

Sort by
0
Rosen
Telerik team
answered on 09 Dec 2013, 09:23 AM
Hello Bob,

As you may know by default the data is send as application/x-www-form-urlencoded. In order to apply different format you will need to use the transport's parameterMap function.

However, I noticed that you have set the type of the DataSource to be aspnetmvc-ajax, which will include (if the script is referenced) a predefined parameterMap build to work with ASP.NET MVC framework. Thus, in make this work you will need to verify that you have included (after the main kendo script file) the kendo.aspnetmvc.min.js file.

Regards,
Rosen
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Bob
Top achievements
Rank 1
answered on 09 Dec 2013, 06:19 PM
Thanks for the info...

I am now able to send correct JSON and get response back correctly (see attached image), but the grid will not bind/display the data.   I know I am close - so what am I missing?    I have my own code that stringify's my object - should I move this to the Parameter Map function?


I have modified the read statement and it now looks like the following:

 var myObject = {};
    myObject["EmployeeID"] = document.getElementById("employee_list").value; //= "14"
    myObject["Address"] = document.getElementById("Address").value;
    myObject["Phone"] = document.getElementById("Phone").value;
    myObject["FirstName"] = document.getElementById("FirstName").value;
    myObject["LastName"] = document.getElementById("LastName").value;
    myObject["SearchSurrogate"] = document.getElementById("searchsurrogate").checked;

    var searchData = JSON.stringify(myObject);
       
    var dataSource = new kendo.data.DataSource({    // create datasource
        transport: {
        
                read: function (options) {
                $.ajax({
                    type: "POST",
                    url: '/Search/Search_Read',  
                    contentType: "application/json; charset=utf-8",
                    data: searchData,
                    dataType: "json",
                    parameterMap: function (data, type) {
                        return kendo.stringify(data);
                    }
                });
                }
                      
        }
    });
var grid = $("#grid").kendoGrid({   // build grid
        dataSource: dataSource,
        height: 430,
        sortable: true,
        resizable: true,
        pageable: true,
        selectable: true,
        columns: [
          { name: "clientID", field: "clientID", hidden:true, title: "C-ID ", width: 20 },
          { name: "propertyID", field: "propertyID", hidden: true, title: "P-ID", width: 20 },
          { name: "loanID", field: "loanID", hidden: true, title: "L-ID", width: 20 },
          { name: "primaryAddress", field: "primaryAddress", title: " ", width: 8 },
          { name: "lastName", field: "lastName", title: "Last Name", width: 90 },
          { name: "firstName", field: "firstName", title: "First Name", width: 90 },
          { name: "spouseLastName", field: "spouseLastName", title: "Spouse Last Name", width: 90 },
          { name: "spouseName", field: "spouseName", title: "Spouse First Name", width: 90 },
          { name: "address", field: "address", title: "Address", width: 100 },
          { name: "city", field: "city", title: "City", width: 80 },
          { name: "initials", field: "initials", title: "Initials", width: 30 },
          { name: "phone", field: "phone", title: "Phone/Email", width: 100 }

        ]
    });
    dataSource.read();
   
});
    dataSource.read();
   
});
0
Rosen
Telerik team
answered on 10 Dec 2013, 07:20 AM
Hi Bob,

There is no parameterMap available to jQuery.ajax method. Also if a custom read function is used, you will need to provide the data to the DataSource via the success callback pass via the methods arguments. Here you can find information on how to handle the read on your own.

Also note that you will need to define a schema data and total in order to map the response.

Regards,
Rosen
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Bob
Top achievements
Rank 1
answered on 11 Dec 2013, 06:41 AM
I am closer, but not working yet:  Attached is the returned schema that contains the total and data schema.... What do you suggest for the final fix?

var dataSource = new kendo.data.DataSource({    // create datasource
        transport: {

            read: {
                type: "POST",
                url: baseURL + "api/search/a/",
                data: data,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (result) {
                    options.success(result);
                }
            },
            parametermap: function (data, type) {
                if (type == "read") {
                    return { models: kendo.stringify(data.models) }
                }
            }
        },
        schema: {
            data: "data"
        }
    });

0
Rosen
Telerik team
answered on 11 Dec 2013, 07:56 AM
Hi Bob,

I suspect there is a JavaScript error in the code you have pasted. The success handler set in the transport uses an options variable, I do not see such variable defined in the provided code. Also if you are using the build-in transport you do not need the success function:

var dataSource = new kendo.data.DataSource({ 
    transport: {
        read: {
            type: "POST",
            url: baseURL + "api/search/a/",
            data: data, // you will need serialize those in the schema
            contentType: "application/json; charset=utf-8",
            dataType: "json"//,
            /*success: function (result) {
                options.success(result); // there is no options variable nor the success is required for the built-in transport
            }*/
        },
        // note the casing of parameterMap
        parameterMap: function (data, type) {
            // there are no model during read operation
           /* if (type == "read") {
                return { models: kendo.stringify(data.models) }
            }*/
            return { data: kendo.stringify(data) }; // serialize the data parameters is some format
        }
    },
    schema: {
        data: "data",
           total: "total"
    }
});


Regards,
Rosen
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Grid
Asked by
Bob
Top achievements
Rank 1
Answers by
Rosen
Telerik team
Bob
Top achievements
Rank 1
Share this question
or