I'm using (and loving) the KendoUI Complete for ASP.NET MVC. I am trying to pass parameters to a page to indicate the filters, sorts, groups, etc. for the grid via the querystring; e.g., http://localhost/MyPage?sort=DatePlaced-desc&page=1&pageSize=15&group=&filter=Id~gte~1719300~and~Id~lte~1800000~and~UserFirstName~eq~'Edward'
When these parameters are passed, I'm wanting the grid on the page to reflect these parameters when it gets created; i.e., the grid should be initially filtered by Id and UserFirstName in accordance with the filters passed to the page.
I'm hoping for something as simple as:
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("MyAction", "MyController"))
.Filter(Request.QueryString["filter"])
.Sort(Request.QueryString["sort"])
.PageSize(Request.QueryString["pageSize"])
)
Your assistance on this would be much appreciated.
Thank you,
Billy McCafferty
2 Answers, 1 is accepted
The Grid will automatically apply the state values if they are in the correct format - Grid Name +"-" + parameter name = value. For example if your Grid is named "Grid" - "http://localhost/MyPage?Grid-sort=DatePlaced-desc". You could also use your current parameters names but you will also need to use the PrefixUrlParameters to disable the prefix e.g.
.PrefixUrlParameters(
false
)
Daniel
the Telerik team
Hi there,
We were using this awesome functionality for years (throughout several versions of Telerik suite) in all the grids, like:
/Products?ProductsGrid-sort=ProductID-desc&ProductsGrid-filter=PartnerID~eq~116~and~Active~eq~true
Also, with multiple combinations of fields and logic operators, always we got this working fine.
But now we are migrating from ASP.NET MVC to ASP.NET Core, version 2022.2.510.
And this feature is not working in Core, just the grids won't recognize the parameters in the Url.
Is there a way to restore this functionality in Core like previous versions?
Thanks.
Hi Mario,
Could you please provide more information about the Grid configuration and the read endpoint? Are you using the Kendo UI for jquery Grid in ASP.NET Core project or you are using the Telerik Asp.Net Core wrappers?
If you need to pass addditional parameters to the remote end point you can use the Data method:
.DataSource(dataSource => dataSource .Ajax() .Read(read => read .Action("Products_Read", "Home") // Set the action method which will return the data in JSON format. .Data("productsReadData") // Specify the JavaScript function which will return the data. ) )
And sample values:
<script>
function productsReadData() {
return {
firstName: "John",
lastName: "Doe"
};
}
</script>
Regards,
Neli
Hi Neli,
We were using Kendo UI v2022.2.510 in the client and Kendo ASP.NET MVC on the server.
And when we pass grid configuration in the querystring to a page containing a grid it'll apply those parameters, for example:
/Products?ProductsGrid-sort=ProductID-desc&ProductsGrid-filter=PartnerID~eq~116~and~Active~eq~true
This is done by kendo libraries, and doesn't have anything to do with the "Data method" at all.
In Daniel's answer he said:
"The Grid will automatically apply the state values if they are in the correct format - Grid Name +"-" + parameter name = value. For example if your Grid is named "Grid" - "http://localhost/MyPage?Grid-sort=DatePlaced-desc"."
That is the functionality we need.
Unfortunately, this no longer works using Kendo UI v2022.2.510 in the client and Kendo ASP.NET Core on the server.
We will appreciate any help on this issue.
Thanks.
Hi Dan,
Thе format of the request shared by Daniel
ProductID-desc&ProductsGrid-filter=PartnerID~eq~116~and~Active~eq~true
is only usable when the type of the DataSource is Ajax. Custom or WebAPI DataSources won't be able to use requests formatted in this way.
That being said you can utilize the query method of the DataSource on the client-side to apply grouping, filtering, sorting, paging, etc with the Read request.
I hope the information above is useful.
If the issue persists, please consider sharing more details about the implementation on your side or an isolated sample project that showcases the experienced behavior.
Hi Stoyan, thanks for your answer. I think an example will help clarify the problem.
This is a simple page with a grid listing some employees:
See Image1.png
And this is the MVC code:
Model ----- public class EmployeesGridViewModel { public EmployeesGridViewModel(Employee employee) { EmployeeID = employee.EmployeeID; Name = employee.Name; Active = employee.Active; Extension = employee.Extension; BuildingAccessIds = employee.BuildingAccessIds; ExpectedEndDate = employee.ExpectedEndDate; } public int EmployeeID { get; set; } [Required] public string Name { get; set; } public bool Active { get; set; } public string Extension { get; set; } public string BuildingAccessIds { get; set; } [DataType(DataType.Date)] public DateTime? ExpectedEndDate { get; set; } }
View
----
<div>
@(Html.Kendo().Grid<EmployeesGridViewModel>()
.Name("employees")
.Columns(cols =>
{
cols.Bound(e => e.EmployeeID).Title("ID").Width(80);
cols.Bound(e => e.Name).DefaultFilterableString();
cols.Bound(e => e.Active).Width(100);
cols.Bound(e => e.Extension).Title("Ext").Width(80);
cols.Bound(e => e.BuildingAccessIds);
cols.Bound(e => e.ExpectedEndDate).Title("Exp. end date");
cols.Command(command =>
{
command.Edit();
}).Width(150);
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Filterable()
.Sortable()
.ColumnMenu()
.Resizable(resize => resize.Columns(true))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(new int[] { 1, 10, 25, 50, 100, 200 })
.Input(true)
.ButtonCount(5)
)
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(e => e.EmployeeID);
model.Field(e => e.EmployeeID).Editable(false);
})
.PageSize(10)
.Filter(filter => filter.Add(e => e.Active).IsEqualTo(true))
.Sort(sort => sort.Add(e => e.Name))
.Read(read => read.Action("Employees_Read", "Admin"))
))
</div>
Controller
----------
public ActionResult Employees_Read([DataSourceRequest]DataSourceRequest request)
{
IQueryable<Employee> employees = db.Employees.Where(e => e.EmployeeID > 0);
return Json(employees.ToDataSourceResult(request, employee => new EmployeesGridViewModel(employee)));
}
In the next picture you can see the request object on the controller in debug mode with the default parameters defined in the view:
See Image2.png
And just modifying the Url we can apply a different filter, for instance if we do:
http://localhost:51068/Admin/Employees?employees-filter=EmployeeID~eq~714
We will get the following result:
See Image3.png
And the filters in the request object now have the new values from the Url:
See Image4.png
This functionality is what we need, and you can notice that we are not using any piece of JavaScript.
These pictures are from our real portal deployed using Telerik ASP.NET MVC v2022.2.510
But now we are migrating to Telerik ASP.NET Core v2022.2.510, and that functionality is not working.
We use this facility extensively and are heavily dependent on it, so any help you can give us will be greatly appreciated.
Thanks,
Mario.
Hi Mario,
Thank you for the clarification.
Based on the provided information the approach you use should work in ASP.NET Core as long as the Action method of the Controller is configured to be called by a GET request.
In addition you need to ensure that the URL indeed calls the Action method.
For example
http://localhost:51068/Admin/Employees?employees-filter=EmployeeID~eq~714
will pass the filter parameters to a method called Employees in the AdminController. However it seems that the method in the Controller is called Employees_Read.
Could you please try using
http://localhost:51068/Admin/Employees_Read?employees-filter=EmployeeID~eq~714
and let me know whether the issue persists.
Hi Stoyan,
The Employees is actually an Action in the controller, like:
public ActionResult Employees() { return View(); }
Which will render the view that contains the grid. So, we are calling the correct action method.
And using the method "Employees_Read" from the url doesn't work.
So, the issue still persists.
Any other idea? Thanks.
Hi Mario,
The Controller indeed has an Action method called Employees however that method is doesn't return data but it returns a View instead. Therefore it won't be able to process the GET request's parameters and respond with the filtered data.
That being said could you please share the errors that you get when you send a request to the Employees_Read method and possibly the headers that can be observed in the Network tab of the browser's Developer Tools?
Currently I suspect that there is mismatch between the type of the request - for example the server might expect a POST request and rejects a GET request to the same endpoint.
Stoyan,
You are completely missing the point of the issue. It actually seems like you don't even understand the basic functionality of the grid and how it operates.
This is VERY simple to recreate. With UI for ASP.NET you can put the filter in the url for a page that displays a grid (not in the datasource url for the grid). The filter will be applied automatically. Do the EXACT same thing with UI for ASP.NET Core and the filter will not be applied.
The earlier response from Telerik in this thread references the method ".PrefixUrlParameters(
false
)
" which will change how the URL parameters are applied. That method does not exist in UI for ASP.NET Core, which is believe is because that functionality simply doesn't exist there. It looks like that functionality wasn't properly ported to .net core.
I found one thing that does work. In UI for ASP.NET MVC the querystring param would be "{gridname}-sort=" and in Core it only works WITHOUT the grid name. The problem with that is it will not work for pages with multiple grids.
Is there a way to configure it to prefix the URL params like was the default in ASP.NET MVC?
-Dan
Hello Mario,
The PrefixUrlParameters method is indeed available only for UI for ASP.NET MVC. As documented in the API if set to true the grid will prefix the query string parameters with its name during server binding. By default the grid will prefix the query string parameters. The key here is the server binding configuration. Server binding for the Grid is available only for Telerik UI for ASP.NET MVC suite, but this functionality is not available in the Telerik UI for ASP.NET Core Grid. This is one of the main differences between both suites and is documented in the Helpers Overview section(fourth point).
By default, when Ajax binding is used the Grid will make a POST request - you can verify this both in the MVC and Core examples for Remote Data Binding of the Grid. With Server Binding the Grid will make a GET request to the action method which initially renders the view and if the PrefixUrlParameters is set to true the query string will contain the Grid's name. The Grid page, sort, filter, and group information is passed as query string parameters in that particular scenario.
If for some reason you need to make a GET request to a Grid's endpoint in ASP.NET Core than you can do so by setting the Type of the request. for example:
.DataSource(dataSource => dataSource .Ajax() .PageSize(20) .Read(read => read.Action("Orders_Read", "Grid").Type(HttpVerbs.Get)) .Filter(filters => { filters.Add(itm => itm.ShipName).Contains("C"); }) )
The above will make a GET ajax request that will look like this: https://demos.telerik.com/aspnet-core/grid/orders_read?sort=&page=1&pageSize=20&group=&filter=ShipName~contains~%27C%27
Here is a sample REPL where you can observe the above. Inspect the network tab and note the query string.
Finally, if you need to pass the Grid Id as an additional parameter the workaround I can suggest is the following:
@(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.OrderViewModel>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("Orders_Read", "Grid").Type(HttpVerbs.Get).Data("function(options) { return additionalData(options, 'grid')}"))
)
)
<script>
function additionalData(e,gridId){
return{
myParam:123,
gridId:gridId
}
}
</script>
Here is a sample REPL demonstrating the above. The query string generated contains the data on sorting, filtering, etc, along with the additional data, including the Grid's id(though not added as a prefix):
https://demos.telerik.com/aspnet-core/grid/orders_read?sort=&page=2&pageSize=20&group=&filter=ShipName~contains~%27C%27&myParam=123&gridId=grid
I hope this helps.