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 React 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
- React
- .NET Core SDK version 2.0 (or later)
- Node.js version 6.0 (or later)
- UI for ASP.NET Core
Setup
-
Create an ASP.NET Core web application that is integrated with React.
-
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
andToDataSourceResult()
from theKendo.Mvc.UI
andKendo.Mvc.Extensions
namespaces. -
Create an endpoint, which will process the requests, by using the
DataSourceRequest
attribute and a model binder. Perform all data operations by using theToDataSourceResult()
method and return the result as JSON.using Microsoft.AspNetCore.Mvc; using reactSpa.Models; using Kendo.Mvc.UI; using Kendo.Mvc.Extensions; namespace reactSpa.Controllers { [Produces("application/json")] [Route("api/Products")] public class ProductsController : Controller { // GET: api/Products [HttpGet] public JsonResult GetProducts([DataSourceRequest]DataSourceRequest request) { // ToDataSourceResult works with IQueryable and thus Entity Framework could be used as a source // instead of an in-memory list. return Json(Products.Items.ToDataSourceResult(request)); } } }
-
Install the Grid package.
-
Install and import one of the KendoReact themes.
-
Create a HOC which will process the requests and parse the response by using the toDataSourceRequestString and translateDataSourceResultGroups Data Query methods.
import React from 'react'; import { toDataSourceRequestString, translateDataSourceResultGroups } from '@progress/kendo-data-query'; export function withState(WrappedGrid) { return class StatefullGrid extends React.Component { constructor(props) { super(props); this.state = { dataState: { skip: 0, take: 20 } }; } render() { return ( <WrappedGrid filterable={true} sortable={true} pageable={{ pageSizes: true }} {...this.props} total={this.state.total} data={this.state.data} skip={this.state.dataState.skip} pageSize={this.state.dataState.take} filter={this.state.dataState.filter} sort={this.state.dataState.sort} onDataStateChange={this.handleDataStateChange} /> ); } componentDidMount() { this.fetchData(this.state.dataState); } handleDataStateChange = (changeEvent) => { this.setState({ dataState: changeEvent.data }); this.fetchData(changeEvent.data); } fetchData(dataState) { const queryStr = `${toDataSourceRequestString(dataState)}`; // Serialize the state. const hasGroups = dataState.group && dataState.group.length; const base_url = 'api/Products'; const init = { method: 'GET', accept: 'application/json', headers: {} }; fetch(`${base_url}?${queryStr}`, init) .then(response => response.json()) .then(({ data, total }) => { this.setState({ data: hasGroups ? translateDataSourceResultGroups(data) : data, total, dataState }); }); } } }
-
Wire the HOC and the Grid component.
import * as React from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { GridColumn, Grid } from '@progress/kendo-react-grid'; import { withState } from './WithState.js'; const StatefullGrid = withState(Grid); class GridExample extends React.Component { constructor(props) { super(props); } render() { return ( <div> <StatefullGrid> <GridColumn field="productId" title="Product Id" filter="numeric" /> <GridColumn field="productName" title="Product Name" /> <GridColumn field="unitsInStock" title="Units In Stock" filter="numeric" /> </StatefullGrid> </div> ); } } export default GridExample;