DataSource - OData v4 filters - fix GUID and substring

6 posts, 0 answers
  1. Casimodo
    Casimodo avatar
    71 posts
    Member since:
    Mar 2015

    Posted 30 Jun 2015 Link to this post

    Hi,

    I'm using row filters in Kendo-grids with "odata-v4" specified on the data-sources. I'm writing here, because I'm not sure if this is a data-source issue or a grid issue. There are two filter scenarios where errors occur on the server side (ASP.NET MVC):

    1) Kendo's current implementation still uses the old "substring" instead of the OData v4 "contains" expression. The server barks.

    2) Since GUIDs are handled as strings, they are wrapped in single quotation marks. The server barks.

    I'm using Kendo UI version 2015.2.624.

    The following hack works around those issues. It would be great if those two scenarios could be fixed in the library.

     

    fixODataV4FilterParameterMap = function (options) {
    // This is needed for Kendo-grid's filters when using OData v4.
     
        // Call the default OData parameterMap.
        var result = kendo.data.transports.odata.parameterMap(options);
     
        if (result.$filter) {
             
            result.$filter = result.$filter.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig, function (x) {
     
            // Remove the single quotation marks around the GUID (OData v4).
            return x.substring(1, x.length - 1);
            });
     
            // Replace "substring" with "contains" (OData v4)
            result.$filter = result.$filter.replace(/substringof\((.+),(.*?)\)/, "contains($2,$1)");
        }
        return result;
    };

     

    Regards,

    Kasimier Buchcik

  2. Casimodo
    Casimodo avatar
    71 posts
    Member since:
    Mar 2015

    Posted 30 Jun 2015 in reply to Casimodo Link to this post

    Just noticed that the above hack fails miserably for multiple substring expressions. E.g.:

    "(substringof('10',Number) and substringof('abcg',Name))"
    incorrectly becomes:
    "(contains(Name,'10',Number) and substringof('abcg'))"

    Does someone have a working strategy at hand here?

  3. Kendo UI is VS 2017 Ready
  4. Casimodo
    Casimodo avatar
    71 posts
    Member since:
    Mar 2015

    Posted 30 Jun 2015 in reply to Casimodo Link to this post

    Ok, this seems to work:

    // Replace "substring" with "contains" (OData v4).
     
    result.$filter = result.$filter.replace(/substringof\((.*?),(.*?)\)/, "contains($2,$1)");

  5. Casimodo
    Casimodo avatar
    71 posts
    Member since:
    Mar 2015

    Posted 30 Jun 2015 in reply to Casimodo Link to this post

    Nope, I forgot the "g" at end:

    result.$filter = result.$filter.replace(/substringof\((.*?),(.*?)\)/g, "contains($2,$1)");

     

     

  6. Casimodo
    Casimodo avatar
    71 posts
    Member since:
    Mar 2015

    Posted 30 Jun 2015 in reply to Casimodo Link to this post

    While debugging in the data-source's code, I learned that there support for OData filter expressions was already implemented. One just has to enable it via parameterMap's argument "useVersionFour". This takes care of the "substring" -> "contains" issue. Only the fixup of the GUID string remains:

    fixODataV4FilterParameterMap = function (data, type) {
        // This is needed for Kendo-grid's filters when using OData v4.
     
        // Call the default OData parameterMap.
        // NOTE: The last boolean parameter indicates that OData v4 is used.
        var result = kendo.data.transports.odata.parameterMap(data, type, true);
     
        if (result.$filter) {
     
            // Remove the single quotation marks around the GUID (OData v4).
            result.$filter = result.$filter.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig, function (x) {               
                return x.substring(1, x.length - 1);
            });           
        }
        return result;
    };

  7. Casimodo
    Casimodo avatar
    71 posts
    Member since:
    Mar 2015

    Posted 01 Jul 2015 in reply to Casimodo Link to this post

    The above is still not correct. One has to call the default OData V4 parameterMap (i.e. not the older OData parameterMap). Otherwise the $inlinecount will not be transformed to $count.

    fixODataV4FilterParameterMap = function (data, type) {
        // This is needed for Kendo grid's filters when using OData v4.
     
        // Call the default OData V4 parameterMap. 
        var result = kendo.data.transports["odata-v4"].parameterMap(data, type);
     
        if (result.$filter) {
     
            // Remove the single quotation marks around the GUID (OData v4).
            result.$filter = result.$filter.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig, function (x) {               
                return x.substring(1, x.length - 1);
            });           
        }
        return result;
    };

     

Back to Top
Kendo UI is VS 2017 Ready