All Components

Integration with UI for ASP.NET Core

The UI for ASP.NET Core and UI for ASP.NET MVC suites provide a DataSourceRequest model binder and a ToDataSourceResult() method which process bulk data operations.

This article demonstrates how to use these features in Angular applications by applying the Data Query helper functions. For the full project source, refer to this GitHub repository.

Sample Integration Project

To implement the sample project:

Prerequisites

Setup

  1. Create an ASP.NET Core web application that is integrated with Angular.

    As a starting point, the sample project uses the Angular project template with ASP.NET Core, which is recommended in the official Microsoft documentation.

  2. Install Telerik UI for ASP.NET Core. For more information, refer to the article on getting started.

    You can skip the UI-related steps because the sample project uses only DataSourceRequest and ToDataSourceResult() from the Kendo.Mvc.UI and Kendo.Mvc.Extensions namespaces.

  3. Create an endpoint, which will process the requests, by using the DataSourceRequest attribute and a model binder. Perform all data operations by using the ToDataSourceResult() method and return the result as JSON.

    using Microsoft.AspNetCore.Mvc;
    using Kendo.Mvc.UI;
    using Kendo.Mvc.Extensions;
    using System.Collections;
    
    namespace dotnet_angular.Controllers
    {
       [Route("api/Products")]
       public class SampleController : Controller
       {
           [HttpGet]
           public JsonResult GetProducts([DataSourceRequest]DataSourceRequest request)
           {
               var result = Json(this.products.ToDataSourceResult(request));
               return result;
           }
    
           private IEnumerable products = new[] {
               new { ProductName = "Chai", CategoryName = "Beverages", QuantityPerUnit = "10 boxes x 20 bags" },
               new { ProductName = "Chang", CategoryName = "Beverages", QuantityPerUnit = "20 boxes x 20 bags" },
               new { ProductName = "Aniseed Syrup", CategoryName = "Condiments", QuantityPerUnit = "12 - 550 ml bottles" },
               new { ProductName = "Chef Anton's Cajun Seasoning", CategoryName = "Condiments", QuantityPerUnit = "48 - 6 oz jars" },
               new { ProductName = "Chef Anton's Gumbo Mix", CategoryName = "Condiments", QuantityPerUnit = "36 boxes" },
               new { ProductName = "Grandma's Boysenberry Spread", CategoryName = "Condiments", QuantityPerUnit = "12 - 8 oz jars" },
               new { ProductName = "Uncle Bob's Organic Dried Pears", CategoryName = "Produce", QuantityPerUnit = "12 - 1 lb pkgs." },
               new { ProductName = "Northwoods Cranberry Sauce", CategoryName = "Condiments", QuantityPerUnit = "12 - 12 oz jars" },
               new { ProductName = "Mishi Kobe Niku", CategoryName = "Meat/Poultry", QuantityPerUnit = "18 - 500 g pkgs." },
               new { ProductName = "Ikura", CategoryName = "Seafood", QuantityPerUnit = "12 - 200 ml jars" }
           };
       }
    }
  4. Install the Data Query and Grid packages.

  5. Create an Angular service which will process the requests and parse the response by using the toDataSourceRequestString, translateDataSourceResultGroups, and translateAggregateResults Data Query methods.

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import {
        toDataSourceRequestString,
        translateDataSourceResultGroups,
        translateAggregateResults,
        DataResult,
        DataSourceRequestState
    } from '@progress/kendo-data-query';
    import { GridDataResult, DataStateChangeEvent } from '@progress/kendo-angular-grid';
    import { Observable } from 'rxjs';
    import 'rxjs/add/operator/map';
    
    @Injectable()
    export class DataService {
        private BASE_URL: string = 'api/Products';
    
        constructor(private http: HttpClient) { }
    
        public fetch(state: DataSourceRequestState): Observable<DataResult> {
            const queryStr = `${toDataSourceRequestString(state)}`; // Serialize the state
            const hasGroups = state.group && state.group.length;
    
            return this.http
                .get(`${this.BASE_URL}?${queryStr}`) // Send the state to the server
                .map(({data, total/*, aggregateResults*/} : GridDataResult) => // Process the response
                    (<GridDataResult>{
                        // If there are groups, convert them to a compatible format
                        data: hasGroups ? translateDataSourceResultGroups(data) : data,
                        total: total,
                        // Convert the aggregates if such exist
                        //aggregateResult: translateAggregateResults(aggregateResults)
                    })
                )
        }
    }
  6. Bind the Grid to the service.

    import { Component } from '@angular/core';
    import { DataService } from './data.service';
    import { Observable } from 'rxjs';
    import { GridDataResult, DataStateChangeEvent } from '@progress/kendo-angular-grid';
    import { DataSourceRequestState, DataResult } from '@progress/kendo-data-query';
    
    @Component({
       selector: 'fetchdata',
       template: `
       <kendo-grid
           [data]="products"
           [pageSize]="state.take"
           [skip]="state.skip"
           [sort]="state.sort"
           [sortable]="true"
           [pageable]="true"
           [scrollable]="'scrollable'"
           [groupable]="true"
           [group]="state.group"
           [filterable]="true"
           [filter]="state.filter"
           (dataStateChange)="dataStateChange($event)"
           [height]="370">
    
           <!-- columns declaration removed for brevity -->
    
       </kendo-grid>
       `
    })
    export class FetchDataComponent {
       public products: GridDataResult;
       public state: DataSourceRequestState = {
           skip: 0,
           take: 5
       };
    
       constructor(private dataService: DataService) {
           this.dataService.fetch(this.state).subscribe(r => this.products = r);
       }
    
       public dataStateChange(state: DataStateChangeEvent): void {
           this.state = state;
           this.dataService.fetch(state)
               .subscribe(r => this.products = r);
       }
    }
In this article