# Integration with UI for ASP.NET Core

[Telerik UI for ASP.NET Core](https://www.telerik.com/aspnet-core-ui) and [Telerik UI for ASP.NET MVC](https://www.telerik.com/aspnet-mvc) include a `DataSourceRequest` model binder and a [`ToDataSourceResult()`](https://docs.telerik.com/aspnet-mvc/api/kendo.mvc.extensions/queryableextensions) extension method. These let the server receive a Kendo UI component data-state object, apply the sort, filter, group, and page operations, and return the result in a format the component can consume directly.

Data Query provides the client-side helpers:

* [`toDataSourceRequestString`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/todatasourcerequeststring)—serializes the component `State` to a query string the `DataSourceRequest` model binder understands.
* [`translateDataSourceResultGroups`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/translatedatasourceresultgroups)—translates the grouped server response into the hierarchical format the component expects.
* [`translateAggregateResults`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/translateaggregateresults)—translates the aggregate portion of the server response.

## How It Works

The integration follows a request-response cycle:

1. The component raises a data-state change event when the user sorts, filters, or pages the data.
2. The application calls [`toDataSourceRequestString`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/todatasourcerequeststring) to serialize the new state.
3. The serialized string is sent to the ASP.NET Core endpoint as a query string.
4. The server deserializes it using the `DataSourceRequest` model binder, applies the operations with `ToDataSourceResult()`, and returns the result as JSON.
5. If the data is grouped, the application calls [`translateDataSourceResultGroups`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/translatedatasourceresultgroups) and [`translateAggregateResults`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/translateaggregateresults) to convert the server response before passing it to the component.

## Server-Side Controller

The following example demonstrates a minimal ASP.NET Core controller that processes a `DataSourceRequest` and returns the result:

```csharp
using Microsoft.AspNetCore.Mvc;
using Kendo.Mvc.UI;
using Kendo.Mvc.Extensions;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public IActionResult GetProducts([DataSourceRequest] DataSourceRequest request)
    {
        // Replace with a database query when using Entity Framework.
        var products = ProductRepository.All().AsQueryable();
        return Ok(products.ToDataSourceResult(request));
    }
}
```

## Client-Side Integration

For a complete, runnable project, see the [Kendo UI for Angular with ASP.NET Core sample](https://github.com/telerik/kendo-angular/tree/master/examples-standalone/kendoangular-aspnetcore-integration) on GitHub. For setup instructions, see [Angular with ASP.NET Core](https://www.telerik.com/kendo-angular-ui-develop/components/installation/dotnet-core).

The [`toDataSourceRequestString`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/todatasourcerequeststring) function accepts a [`DataSourceRequestState`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/datasourcerequeststate), which extends the base [`State`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/state) type with an `aggregates` field.

The following example demonstrates a service method that fetches Grid data from the ASP.NET Core endpoint:

```ts
import { toDataSourceRequestString, translateDataSourceResultGroups } from '@progress/kendo-data-query';
import { DataSourceRequestState, GridDataResult } from '@progress/kendo-angular-grid';

public getProducts(state: DataSourceRequestState): Observable<GridDataResult> {
    const queryStr = toDataSourceRequestString(state);
    const hasGroups = state.group && state.group.length;

    return this.http.post<GridDataResult>(`api/products?${queryStr}`, {}).pipe(
        map(({ data, total }) => ({
            // Only grouped responses need remapping to the hierarchical format the Grid expects.
            data: hasGroups ? translateDataSourceResultGroups(data) : data,
            total
        }))
    );
}
```

## See Also

* [Data Query Overview](https://www.telerik.com/kendo-angular-ui-develop/components/data-query)
* [`toDataSourceRequestString`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/todatasourcerequeststring)
* [`translateDataSourceResultGroups`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/translatedatasourceresultgroups)
* [`translateAggregateResults`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/translateaggregateresults)
* [`DataSourceRequestState`](https://www.telerik.com/kendo-angular-ui-develop/components/data-query/api/datasourcerequeststate)
