KendoGridBinderEx - No property or field exists in type

asp.net-web-api automapper-3 c# dynamic-linq kendo-grid

Question

I am using AngularJS along with KendoUI to create a grid, which gets its data from a WebAPI webservice. For the grid, I want to allow server-side sorting, paging, filtering, and grouping. For this purpose, I am trying to use the KendoGridBinderEx library.

I have downloaded the KendoGridBinderEx source, run the example project, and it works fine. However, when I do the exact same thing in my project, I get the following error when I try to do a filter on a column in the grid:

System.Linq.Dynamic.ParseException: No property or field 'test' exists in type 'MyEntity'

"test" is what I am typing into the filter, so it should be the filter text; it should not be looking for a property or field called "test".

I have debugged and used Fiddler to see that the filter part of the request being sent over in the request is exactly the same as the working request in the examples, so I don't think the problem is on the request side.

For all my code blocks, I am simplifying everything to save space, and to cut out things that are not relevant. For instance, I am cutting out my database code, and generating a list of entities on the fly, since doing so still exhibits the problem, hence I know that it is not a problem with my Entity Framework code.

Here is my JS code:

    var myDataSource = {
        transport: {
            read: {
                url: function () {
                    return url;
                },
                type: 'post',
                dataType: 'json'
            },
            parameterMap: function (options, operation) {
                if (options.filter) {
                    KendoGrid_FixFilter(myDataSource, options.filter);
                }

                if (operation === "read") {
                    // convert the parameters to a json object
                    return kendo.stringify(options);
                }

                return options;
            }
        },
        serverPaging: true,
        serverSorting: true,
        serverFiltering: true,
        serverGrouping: true
        schema: {
            data: 'data',
            groups: 'groups',
            aggregates: 'aggregates',
            total: 'total',
            model: {
                id: "id",
                fields: {
                    id: { type: "number" },
                    name: { type: "string" },
                    description: { type: "string" }
                }
            }
        },
    };

And here is my WebAPI Controller code:

    [System.Web.Http.Route("api/MyEntity")]
    [System.Web.Http.HttpPost]
    public KendoGridEx<MyEntity, MyEntity> GetMyEntities(KendoGridApiRequest request)
    {
        var entList = new List<MyEntity>();
        for (int i = 0; i < 10; i++)
        {
            var newEntity = new MyEntity
            {
                Id = i,
                Name = "test",
                Description = "description"
            };
            entList.Add(newEntity);
        }
        return entList.AsQueryable().ToKendoGridEx<MyEntity, MyEntity>(request);
    }

So if I set a "contains" filter on the "Name" column with a value of "test" I get the above-mentioned error. Any ideas as to why?

1
1
9/2/2015 3:04:17 PM

Popular Answer

What you can do is modify the property names before kendo-grid sends these to the server.

So the filter.field value 'name' is converted to 'Name'.

See this modified KendoGrid_FixFilter javascript function:

// kendoDataSource = kendo.data.DataSource
// filter = kendo filter
function KendoGrid_FixFilter(kendoDataSource, kendoFilter, depth) {
    if ((!kendoDataSource) || (!kendoFilter)) return;

    if (!depth) depth = 0;
    // console.log(depth + " - FixDatesInFilter:" + JSON.stringify(kendoFilter));

    $.each(kendoFilter.filters, function (idx, filter) {
        //console.log("filter = " + idx + " = " + JSON.stringify(filter));

        if (filter.hasOwnProperty("filters")) {
            depth++;
            KendoGrid_FixFilter(kendoDataSource, filter, depth);
        }
        else {
            $.each(kendoDataSource.schema.model.fields, function (propertyName, propertyValue) {

                if (filter.field == propertyName) {
                    // console.log("before = " + filter.field);
                    filter.field = filter.field.toPascalCase();
                    // console.log("after = " + filter.field);
                }

                if (filter.field == propertyName && propertyValue.type == 'date') {
                    filter.value = kendo.toString(filter.value, _DefaultDateFormat); // "MM/dd/yyyy"
                    // console.log("changed = " + filter.value);
                }
            });
        }
    });
}

You do already use this function in the datasource.

Example code for CamelCase/PascalCase could be something like this:

String.prototype.toCamelCase = function () {
    console.log("String.prototype.toCamelCase");
    return this
        .replace(/\s(.)/g, function ($1) { return $1.toUpperCase(); })
        .replace(/\s/g, '')
        .replace(/^(.)/, function ($1) { return $1.toLowerCase(); });
};

String.prototype.toUpperCaseFirstChar = function () {
    console.log("String.prototype.toUpperCaseFirstChar");
    return this.substr(0, 1).toUpperCase() + this.substr(1);
};


String.prototype.toPascalCase = function () {
    console.log("String.prototype.toPascalCase");
    return this.toCamelCase().toUpperCaseFirstChar();
};
0
9/4/2015 6:50:52 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow