Kendo UI for jQuery Gird Web API 404 - asp.net-web-api

I am using Kendo UI for jQuery Gird to get some data populated from ASP.NET Web API. The data loads as expected and everything works fine. However, ever since I have enabled server side filtering (which is still an issue to deal with as asked in prior question: here) I am often getting 404 error whenever some filter is applied.
Not always the request to filter records fail but this happens occasionally and not always. I am unable to identify the root cause for it.
So far what I am sure about is that there is no network related issue causing this (as have tested on local machine).
The only issue that I am focused here is the occasional 404 in case filters are being passed with the request.
Also following is datasource configurations:
dataSource: {
transport: {
read: {
type: "POST",
url: "/api/MyController"
}
},
schema: {
model: {
fields: {
...
}
},
data: "data",
total: "total",
aggregates: "aggregate"
},
serverPaging: true,
serverSorting: true,
serverAggregates: true,
serverFiltering: true,
pageSize: 20,
aggregate: [
...
],
}

Seems like the query parameter got too long in case of passing multiple filters and server rejected the request.
One possible solution was to increase the allowed query parameter length (which I did not use).
Alternatively I switched the request to POST (now having the filters being passed as part of the body) and it resolved my issue.
transport: {
read: {
type: "POST",
url: "/api/Data/MyData"
}
}

Related

SharePoint 2013 and Kendo Grid cross domain call issues

I am having a small issue that I just can't seem to figure out. I am trying to make a simple SharePoint 2013 demo app that gets a few fields from a list on the parent site and binds to a kendo grid.
Due to the new nature of SP2013, app's get created in their own local site which makes these calls cross domain. When I make the call, no data is pulled back. When I compare a working call vs the call being made by the app, I can see that a cookie is not present in the call that is failing (which is why no data is being pulled back). If anyone could offer any hints or suggestions on things to try, I would appreciate it.
The List I am trying to call is called KendoGridList and I am trying to pull back the first and last name and bind to the grid. Below is my code:
EDIT: After looking into the code a little deeper, it looks like a cookie is not getting passed in the call to the service. If I take the cookie from a normal rest call to the service which works and add it to the composer in fiddler the call goes through and returns data.
$(document).ready(function () {
$("#grid").empty();
var siteUrl = "site url placed here";
var url = siteUrl + "/_vti_bin/Listdata.svc/KendoGridList/?$select=FirstName,LastName";
grid = $("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: {
url: url,
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json;odata=verbose");
}
}
},
schema: {
type: "json",
model: {
fields: {
FirstName: "FirstName",
LastName: "LastName"
}
}
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
change: function (e) { // data load completed for grid
},
},
filterable: false,
sortable: true,
pageable: true,
scrollable: false,
//groupable: true,
columns: [{
field: "FirstName",
title: "First Name",
width: 50
}, {
field: "LastName",
title: "Last Name",
width: 50
}
]
});
});
I've also tried using:
read: {
url: url,
type: "GET",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
},
If you are using a provider-hosted app you should try using the SP cross-domain library. I think your best bet is to retrieve the data using the library and then bind the resulting info to the grid.
http://blogs.msdn.com/b/officeapps/archive/2012/11/29/solving-cross-domain-problems-in-apps-for-sharepoint.aspx

extjs TreeStore proxy with dynamic update api

From my extended Ext.data.TreeStore:
proxy: {
type: 'ajax',
api: {
read: "/GetTree.json",
update: "/SetTree.aspx?username=user1"
},
reader: {
type: 'json',
root: 'children'
},
listeners: {
exception: function (proxy, response, options) {
// error case
console.log('Exception in Portlets store proxy...');
console.log(response);
}
}
},
What I am trying to figure out is how can I make the username=user1 dynamic, such that I could pass in user2 and have the aspx page process with that user data.
I cannot figure out if/how TreeStore.sync() allows parameters to be passed into it.
Update:
What I am really after here is the ability to save back the entire tree structure as a JSON string instead of just the record that was updated. I can build the JSON string I need to pass but cannot figure out how to actually get that information to my SetTree.aspx page.
You can try setting extra params on the proxy before calling sync:
store.proxy.extraParams = { param1 : '', param2 : '' };
There is anecdotal evidence that suggests this works in 4.1.3 but not earlier versions.
Another thought is to just fire a regular Ajax.request and send desired params along instead of using the tree store to do that.
I know this is old, but for people like me that were searching for the same question...
If you want to save the entire structure instead of just the modified lines, you need to define a writer in your store proxy and in that writer, set writeAllFields: false:
proxy: {
type: 'ajax',
api: {
read: "/GetTree.json",
update: "/SetTree.aspx?username=user1"
},
reader: {
type: 'json',
root: 'children'
},
listeners: {
exception: function (proxy, response, options) {
// error case
console.log('Exception in Portlets store proxy...');
console.log(response);
}
},
writer: {
type: 'json',
writeAllFields: true
}
},

Kendo DataSource: How to set filters before fetch without sending two httprequests

Environment:
kendo version: 2013.1.319
dataSource:
productsDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: "http://www.mydomain.com/odata.svc/products",
dataType: "json",
contentType: "application/json"
}
schema: {
type: "json",
data: function(data){
return data.value;
},
total: function(data){
return data['odata.count'];
},
model: product
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true
});
Get data:
productsDataSource.filter([{ field: "Id", operator: "eq", value: 5 }]); //this will send an httprequest
productsDataSource.fetch(function (e) {
tempDataStorage = e.items;
//more logic to dealing with the data;
});
problems:
need to use the fetch method of the dataSource for data processing(widgets initialization, data binding...etc);
avoid sending two httprequests when setting filters before fetch;
the filter condition need to be changed at runtime.
productsDataSource._filter = { logic: 'and', filters: [
{ field: "Id", operator: "eq", value: 5 }]};
I've found this to work. Set the internal property to a full filter object. You can then call fetch afterwards. I've not yet found a way to change the page size without triggering a fetch however.
You can user filter in the DataSource configuration. This should issue only one request with the filtering conditions that you specify in the DataSource configuration.
Set the _filter field in the dataSource using productsDataSource._filter = [{ field: "Id", operator: "eq", value: 5 }]; and then manually initiate the request for remote data when you are ready using productsDataSource.read();
Even though it is an old question, it comes in google results. So even though I don't know if it is valid for kendo version: 2013.1.319, but there is currently a method
dataSource.query({
sort: { field: "ProductName", dir: "desc" },
page: 3,
pageSize: 20
});
This can set multiple options like sort, filter paging etc in a single call and returns a promise.
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-query
Bind event listener to datasource which initializes widget and then use filter method.
datasource.one('requestEnd', function(){
// initialize or/and bind widget
});
datasource.filter({ /*your filter*/ })

Kendo Combobox works with odata localhost but fails in production

So I have a really strange problem with the kendo web combobox with odata with serverFiltering: true
If I use it on a localhost server, it requests odata format and works great. Doesn't matter if it's pointing to an external server for the data (using CORS) or not. Either way it works great and gets data back the way it's supposed to etc.
However, as soon as I put it on a public domain, using the same browser it fails. And it fails in a most bizzare way:
It stops passing the $filter property. AND it stops calling the scheme.data function to parse the result properly (it successfully calls and gets ALL of the resultset because of no filter).
Further, it doesn't apply the results to the drop down, so it stays empty.
Absolutely no javascript errors are thrown. Putting breakpoints on the function for schema.data results in it never getting hit in IE or chrome. Same goes for change event and error events. Nothing.
Here's the data source:
dsContacts = new kendo.data.DataSource({
type: "odata",
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 20,
transport: {
read: {
url: User.serviceUrl + "/contact/list"
}
},
schema: {
data: function (data) {
if(dsLinks.selectedItem().LinkedToContactID() && dsLinks.selectedItem().LinkedToContact()) {
data.results.push({
ID: dsLinks.selectedItem().LinkedToContactID(),
Name: dsLinks.selectedItem().LinkedToContact()
});
}
return data.results;
}
},
error: function (e) {
tradepointUtilities.ShowErrorAlert("Contact List Get", e);
}
});
And the combo is defined as:
$("#cbo").kendoComboBox({
dataTextField: "ID",
dataValueField: "Name",
suggest: true,
datasource: dsContacts,
filter: "contains",
autoBind: false,
delay: 300,
minLength: 3
});
Again, works perfectly on localhost, fails in all browsers exactly the same way in production without any errors.
Ideas?

How to pass page size, filters and sort parameters to back- end in Kendo UI Grid?

I am trying to use Kendo UI grid with remote data source, but cannot understand how to pass page size, filters and sort parameters to the ASP.Net aspx page that return a json string for grid's data source. Telerik's documentation on Kendo UI is bad because they have no examples on using server-side technologies with Kendo UI. If someone knows this please let me know?
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: "GetProducts.aspx"
},
schema: {
model: {
fields: {
ProductId: { type: "number" },
ProductName: { type: "string" },
CategoryName: { type: "string" },
IncludeProduct : { type: "boolean" }
}
}
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
In GetProducts.aspx page, I create a json string in page load event and send it back to browser. I am using ASP.Net Webforms.
The parameters are passed automatically in the server request. You need to look at the requests being made (ie Firebug addon for FireFox) to see them all but some of them are skip, take, filter[logic],sort[i][dir], sort[i][field] etc.
If your page number is 3 and your page size is 100 then the skip value passed would be 200 and the take would be 100.
To modify these to pass under different names you would need to use the parameterMap Kendo provides but I don't have experience with that.
I don't have familiarity with ASP.Net Web Forms to know for sure but I wrote this after a basic google search so you can get the basic idea for pulling the parameter.
protected void Page_Load(object sender, EventArgs e)
{
string skip = Request.QueryString["skip"];
}

Resources