The way toJSON outputs will yield to this kind of behavior in HTTP Posts.
Name | Value
items[0][Name] | Name 1
items[0][Id] | a
items[1][Name] | Name 2
items[1][Id] | b
items[0].Name | Name 1
items[0].Id | a
items[1].Name | Name 2
items[1].Id | b
This is a pretty egregious problem, as it makes it very difficult and confusing to rely on the tools, because now I know that anything that Kendo's internals use that implements toJSON is completely unsuitable for any kind of method calls.
Is there any chance this can get fixed soon?
7 Answers, 1 is accepted
This is the default format used by jQuery to serialize nested objects when making an ajax request. The Kendo UI DataSource relies entirely on jQuery.ajax when doing ajax requests. The problem isn't related with the way the toJSON method of the ObservableObject works.
The function used by jQuery.ajax to do serialization is jQuery.param. Here is a live demo which shows how it behaves with nested objects: http://jsbin.com/oxorUvu/1/edit. It yields the exact same format you have seen.
There are two ways to deal with this behavior:
1. Send your data in JSON format:
<
script
>
var dataSource = new kendo.data.DataSource({
transport: {
create: {
dataType: "jsonp" // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
},
parameterMap: function(data, type) {
return kendo.stringify(data);
}
},
batch: true,
schema: {
model: { id: "ProductID" }
}
});
dataSource.add( { ProductName: "New Product" });
dataSource.sync();
</
script
>
2. Implement a custom transport for your data source and do the serialization manually in the desired format:
<
script
>
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
// make JSONP request to http://demos.kendoui.com/service/products
$.ajax({
dataType: "jsonp", // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
data: /* serialize your data here */,
success: function(result) {
// notify the data source that the request succeeded
options.success(result);
},
error: function(result) {
// notify the data source that the request failed
options.error(result);
}
});
}
}
});
dataSource.fetch(function() {
console.log(dataSource.view().length); // displays "77"
});
</
script
>
Regards,
Atanas Korchev
Telerik


$.ajax({
type: "POST",
url: "/administrator/attendance/save2",
dataType: "jsonp",
parameterMap: function (data, type) {
return {
model: kendo.stringify(data)
}
}
});
The code you have pasted is not valid. It is a mix of the solutions I have provided. The $.ajax doesn't have a parameterMap method. The Kendo data source does.
How you would implement the same if Kendo UI weren't involved? How would you send a complex object to your action method? I am sure the same approach could be easily used with Kendo UI observable objects.
Atanas Korchev
Telerik

I think the problem is that you guys have deceptively named this method. It is not "toJSON", it is "toJS", or "toJavascript".
Your ".toJSON" method converts an observable into raw Javascript without all of the other stuff. This is fine, since it is often desired, but it is certainly different than "toJSON".
I would expect a 'toJSON' method to behave the same way kendo.stringify works, only sound far less silly than "stringify" and account for any awkward behavior imposed by the existence of observable object.
This code works just fine in KnockoutJS, also, so ... this is how I would do it.
$.ajax({
type: "POST",
url: "/administrator/attendance/save2",
dataType: "json",
data{ model: viewModel.toJSON() }
});

I absolutely love the Kendo framework, but there are just little quirks and convention mistakes like this that make me shake my head and wonder what the developers were thinking at the time. I'm unclear how anyone believed that this method is the same as pure JSON, as JSON is usually only useful when sent over the word, and rarely has any place in actual javascript code. Because within actual javascript code, it is just "javascript".
I suppose the only logical argument I can reach is that converting everything to raw javascript as the "toJSON" method facilitates the process by giving you a
simple object that you can convert by yourself.
But I don't agree, to be honest. I would much rather see "toJSON" renamed to "toJS" like it is in KnockoutJS, and then an actual "toJSON" method implemented that essentially overloaded or called upon the stringify method, with any customization Kendo needed for its observables.
There seems to be some misunderstanding. The toJSON method is something used by JSON.stringify to perform JSON serialization. We didn't pick neither the toJSON name nor the stringify name - it is the standard. The kendo.stringify method is a wrapper for JSON.stringify because the latter isn't available in IE7. So we are not considering those convention mistakes - those are official conventions defined by the W3C and supported by all modern browsers.
The code you have posted won't work. To post JSON via $.ajax the data option must be a string and not an object. Otherwise you would end up with the initial problem being discussed here. To post JSON to ASP.NET MVC you need to serialize your data as JSON and pass it as the data option of $.ajax. More details can be found here: http://stackoverflow.com/questions/14752522/post-json-to-asp-net-mvc-4-action-from-jquery
Atanas Korchev
Telerik