JSON encoded improperly when using KendoGrid POST

2019-09-05 22:21发布

I am binding to a JSON data source, then rebinding after the user initiates a search based on filters on the page. The JSON payload is encoded improperly and nothing I've tried thus far seems to explain why.

If I could just add the correct JSON to the HTTP post, everything would work normally, and does with the $.ajax method listed first.

Using $.ajax call (works)

 $.ajax(
                   {
                       url: '/api/DataProcessing',
                       type: "Post",
                       contentType: "application/json; charset=utf-8",
                       data: '' + JSON.stringify(searchObject),
                       dataType: 'json',
                       success: function (result) {
                           $(".kendoDataProcessing").data("kendoGrid").dataSource = new kendo.data.DataSource({ data: result });
                           $(".kendoDataProcessing").data("kendoGrid").dataSource.read();
                           $(".kendoDataProcessing").data("kendoGrid").refresh();

                       },
                       error: function (xhr, ajaxOptions, thrownError) {
                           alert('Status: ' + xhr.status + ', Error Thrown: ' + thrownError);
                       }
                   });

However, when I update the kendogrid data source in what I expect to send an equivalent payload, it encodes the JSON in an unexpected way (see below the code block for before and after HTTP requests captured in Fiddler. (encodes improperly)

   $(".kendoDataProcessing").kendoGrid({
                        dataSource: {
                            transport: {
                                read: {
                                    url: '/api/DataProcessing',
                                    type: 'Post',
                                    contentType: 'application/json; charset=utf-8',
                                    data: '' + JSON.stringify(searchObject),
                                    dataType: 'json',
                                }
                            },
                            pageSize: 25
                        },

                        height: 620,
                        sortable: true,
                        pageable: true,
                        filterable: true,
                        columns: [
                            {
                                field: "Client",
                                title: "Client Name",
                                width: 120
                            }, {
                                field: "Study",
                                title: "Study",
                                width: 100
                            }, {
                                field: "DataLogId",
                                title: "Batch Description",
                                width: 120
                            }, {
                                field: "Indicator",
                                title: "Indicator",
                                width: 100
                            }, {
                                field: "UserName",
                                title: "Username",
                                width: 110
                            }, {
                                field: "AssessmentPoint",
                                title: "Assessment Point",
                                width: 130
                            }, {
                                field: "DateStamp",
                                title: "Date Stamp",
                                width: 180
                            }]
                    });

**Expected JSON encoding (HTTP call created using $.ajax method) **

{"Client":"Choose a client...","Study":"Choose a study...","UserName":"Choose a user...","from":"","To":"","AssessmentPoint":"Choose an AP...","Indicator":"Choose an indicator...","DataLogId":""}

**Actual JSON encoding (HTTP call created using Kendogrid data source update and rebind **

0=%7B&1=%22&2=C&3=l&4=i&5=e&6=n&7=t&8=%22&9=%3A&10=%22&11=C&12=h&13=o&14=o&15=s&16=e&17=+&18=a&19=+&20=c&21=l&22=i&23=e&24=n&25=t&26=.&27=.&28=.&29=%22&30=%2C&31=%22&32=S&33=t&34=u&35=d&36=y&37=%22&38=%3A&39=%22&40=C&41=h&42=o&43=o&44=s&45=e&46=+&47=a&48=+&49=s&50=t&51=u&52=d&53=y&54=.&55=.&56=.&57=%22&58=%2C&59=%22&60=U&61=s&62=e&63=r&64=N&65=a&66=m&67 ... (continues)

It looks like it is making the json string into an array of sorts. So I tried with just a test string of "floof" and it encoded to "0=f&1=l&2=o&3=o&4=f"

Controller method called:

  public HttpResponseMessage Post([FromBody]DataProcessingSearch dataProcessingSearch)
  {
      // dataProcessingSearch var is null (was passed oddly encoded)     
  }

Additional Details (search object)

 var searchObject = new Object();
                    searchObject.Client = $('#ClientList').val();
                    searchObject.Study = $('#StudyList').val();
                    searchObject.Site = $('#SiteList').val();
                    searchObject.UserName = $('#UserList').val();
                    searchObject.from = $('#beginSearch').val();
                    searchObject.To = $('#endSearch').val();
                    searchObject.AssessmentPoint = $('#AssessmentPointList').val();
                    searchObject.Indicator = $('#IndicatorList').val();
                    searchObject.DataLogId = $('#DataLogIdText').val();

3条回答
Root(大扎)
2楼-- · 2019-09-05 22:50

demo: http://so.devilmaycode.it/json-encoded-improperly-when-using-kendogrid-post-payload

function searchObject(){ 
    return { 
        Client : $('#ClientList').val(),
        Study : $('#StudyList').val(),
        Site : $('#SiteList').val(),
        UserName : $('#UserList').val(),
        from : $('#beginSearch').val(),
        To : $('#endSearch').val(),
        AssessmentPoint : $('#AssessmentPointList').val(),
        Indicator : $('#IndicatorList').val(),
        DataLogId : $('#DataLogIdText').val()
    }
}

// i have putted the dataSource outside just for best show the piece of code...
var dataSource = new kendo.data.DataSource({
    transport: {
        read : {
            // optional you can pass via url 
            // the custom parameters using var query = $.param(searchObject())
            // converting object or array into query sring
            // url: "/api/DataProcessing" + "?" + query,
            url: "/api/DataProcessing",
            dataType: "json",
            // no need to use stringify here... kendo will take care of it.
            // also there is a built-in function kendo.stringify() to use where needed.
            data: searchObject
        },
        //optional if you want to modify something before send custom data...
        /*parameterMap: function (data, action) {
            if(action === "read") {
                // do something with the data example add another parameter
                // return $.extend({ foo : bar }, data);
                return data;
            }
        }*/
    }
});

$(".kendoDataProcessing").kendoGrid({
    dataSource: dataSource, 
    ...
});

comments are there just for better explanation you can completely remove it if don't need it. the code is fully working as is anyway.

查看更多
神经病院院长
3楼-- · 2019-09-05 22:53

I remember working with a kendo grid in the past. Solution back then was returning jsonp. (needed to work crossdomain not sure if it does in your case)

Suggestion change you controller method to return sjonp by decorating you method with a JsonpFilterAttribute. Something like so:

[JsonpFilter]
public JsonResult DoTheThing(string data, string moreData)
{
  return new JsonResult
  {
     Data = FetchSomeData(data, moreData)
  };
}

Then in de Kendo grid try use http://demos.telerik.com/kendo-ui/datasource/remote-data-binding.

For the Jsonpfilter attribute first look at here or else here.

查看更多
爷、活的狠高调
4楼-- · 2019-09-05 23:03

What May be the wrong perception:-

1.The Json() method accepts C# objects and serializes them into JSON strings. In our case we want to return an array of JSON objects; to do that all you do is pass a list of objects into Json().

public JsonResult GetBooks()  
{
    return Json(_dataContext.Books);
}

Can you identify what is wrong with the above method? If you didn't already know, the above method will fail at runtime with a "circular reference" exception.

Note: try to return Json, HttpResponse may serialize the data in such a way that it is not acceptable by Kendo Grid. this has happened with me in my project.

Try this Approach:- Now lets create instances of them in a JsonResult action method.

public JsonResult GetFooBar()  
{
    var foo = new Foo();
    foo.Message = "I am Foo";
    foo.Bar = new Bar();
    foo.Bar.Message = "I am Bar";
    return Json(foo);
}

This action method would return the following JSON:

{
    "Message" : "I am Foo",
    "Bar" : {
        "Message" : "I am Bar"
    }
}

In this example we got exactly what we expected to get. While serializing foo it also went into the Bar property and serialized that object as well. However, let's mix it up a bit and add a new property to Bar.

查看更多
登录 后发表回答