0

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();
Chris Ballance
  • 33,810
  • 26
  • 104
  • 151
  • see my response, i have also provided a working demo, you can look in the source code.. hope this help. PS: i'm not using ASP but this issue is not related to the server side. – Luca Filosofi Aug 13 '14 at 12:59

3 Answers3

4

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.

Vishal
  • 537
  • 3
  • 13
4

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.

Luca Filosofi
  • 30,905
  • 9
  • 70
  • 77
2

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.

Community
  • 1
  • 1
Igor
  • 298
  • 3
  • 8