Grid Create & Update sending malformed JSON to server

6 posts, 0 answers
  1. Bob
    Bob avatar
    17 posts
    Member since:
    Aug 2013

    Posted 06 Dec 2013 Link to this post

    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 }
                                 }
                         }
                     }
                 }
             });
       });
  2. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 09 Dec 2013 Link to this post

    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!
  3. Bob
    Bob avatar
    17 posts
    Member since:
    Aug 2013

    Posted 09 Dec 2013 Link to this post

    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();
       
    });
  4. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 10 Dec 2013 Link to this post

    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!
  5. Bob
    Bob avatar
    17 posts
    Member since:
    Aug 2013

    Posted 11 Dec 2013 Link to this post

    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"
            }
        });

  6. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 11 Dec 2013 Link to this post

    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!
Back to Top