0
votes

I’m smashing my head for few days already trying to get grid server site filtering working for my Angular 6 and Kendo UI. When I set filter on the UI I can see data in posted body of the message like “filter=Item~contains~'SL-'&page=1&pageSize=5” however this information is not mapped correctly on the MVC controller site to DataSourceRequest object This is my Angular service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Headers, Response, RequestOptions, RequestMethod } from '@angular/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 { catchError, map, tap } from 'rxjs/operators';
import { sampleProducts } from '../delivery-manager/products'
import { HttpHeaders } from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class DeliveryDataSvrService {
    private BASE_URL: string = 'GetDeliveryDetailsForGrid';
    //private BASE_URL: string = 'DeliveryManager/GetDeliveryDetailsForGrid';
    constructor(public http: HttpClient) {

    }

    public fetch(state: DataSourceRequestState): Observable<DataResult> {



        return this.http
            .post<DataResult>(this.BASE_URL, toDataSourceRequestString(state)) 
            .map((data: any) =>
                (<GridDataResult>{
                    data: data.Data,
                    total: data.Total,
                })
            )

    }
}

This is my MVC controller

using DataAccess;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;

namespace KingspanAUGears.Controllers
{
    public class DeliveryManagerController : Controller

        [System.Web.Http.HttpPost]
        public ActionResult GetDeliveryDetailsForGrid( [DataSourceRequest] DataSourceRequest request)
        {
            // request is null for PageSize, Filters, Sorts 


            var ctx = new KingspanAUToolsEntities();
            var toReturn = ctx.TruckDriversJobDetails.Take(100).ToDataSourceResult(request);
            return Json(toReturn);

        }
    }
}
2

2 Answers

0
votes

The DataQuery toDataSourceRequestString function creates a query string that will be properly parsed by the DataSourceRequest model binder in the Controller, and is supposed to be used with a GET request:

Documentation article and example

If needed, perhaps you can tweak the Angular data service as follows to send the state in a POST request:

public fetch(state: DataSourceRequestState): Observable<any> {
    const queryStr = `${toDataSourceRequestString(state)}`; //serialize the state
    const hasGroups = state.group && state.group.length;

    const obj = toDataSourceRequest(state);
    const httpOptions = {
        headers: new HttpHeaders({
            'Content-Type': 'application/x-www-form-urlencoded'
        })
    };

    return this.http
        .post(`${this.BASE_URL}`, queryStr, httpOptions) //send the state to the server         
        .map((res:any) => // process the response
            (<GridDataResult>{
                //if there are groups convert them to compatible format
                data: hasGroups ? translateDataSourceResultGroups(res.Data) : res.Data,
                total: res.Total,
                // convert the aggregates if such exists
                //aggregateResult: translateAggregateResults(aggregateResults)
            })
        )
}

Controller:

 [HttpPost]
    public JsonResult PostProducts([DataSourceRequest]DataSourceRequest request)
    {

        var result = Json(this.products.ToDataSourceResult(request));
        return result;
    }

    private IEnumerable products = new[] {
        new { ID = 1, Name = "Smith" },
        new { ID = 2, Name = "John" }
    };
0
votes

Did you try the suggested adjustments? Here is a screenshot of the request received on my end when I type "s" in the Name column Grid filter:

enter image description here

The Content-Type in the HttpHeaders needs to be 'application/x-www-form-urlencoded' and the filters get mapped as expected: