使用Kendoui网格的Odata v4包含过滤器

时间:2014-08-05 11:03:36

标签: asp.net-web-api kendo-grid odata kendo-asp.net-mvc

使用odata v4的asp.net web api Web服务使包含过滤器的最简单方法是什么?

似乎使用odata v4的Web服务不再承认'substringof'函数并且想要'contains'函数。

示例:使用网格中WorkUnitCode列的Contains过滤器进行GET并输入'xYz'。 substringof(失败)

http://localhost:1486/odata/BillOfMaterials(2)/BillOfMaterialsItems?$format=json&$top=10&$filter=substringof('xYz',WorkUnitCode)&$count=true

要使用contains函数需要GET:

http://localhost:1486/odata/BillOfMaterials(2)/BillOfMaterialsItems?$format=json&$top=10&$filter=contains(WorkUnitCode,'xYz')&$count=true

我相信有两种方法可以解决这个问题,并且不确定哪种方法更好或者如何解决这两种解决方案的问题。

方法1:拦截请求并将其更改为使用包含反转参数的函数。 方法2:将子串功能添加到web api。

6 个答案:

答案 0 :(得分:10)

更新由于Kendo now supports ODATA V4不再需要调整才能使其正常运行。

更改数据集类型

type: 'odata'

type: 'odata-v4'

应该做的伎俩。示例源代码为here

答案 1 :(得分:4)

以下是使用正则表达式替换的Ryan Mrachek答案的通用版本。

parameterMap: function (data) {
    var d = kendo.data.transports.odata.parameterMap(data);
    if (d.$inlinecount) {
        if (d.$inlinecount == "allpages") {
            d.$count = true;
        }
        delete d.$inlinecount;
    }
    if (d.$filter) {
        d.$filter = d.$filter.replace(/substringof\((.+),(.+)\)/, "contains($2,$1)");
    }
    return d;
}

答案 2 :(得分:4)

@Gongdo Gong提供的版本并不完美,如果表达式以双括号结尾,则失败。

示例:

"(Id gt 2 and substringof('desde',Nombre))".replace(/substringof\((.+),(.+)\.)/, "contains($2,$1)")

返回:

(Id gt 2并包含(Nombre),'desde'))

需要更改表达式:

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

答案 3 :(得分:3)

使用更简单的JS解决方案,其中截取并更改parameterMap以适应新的ODATA v4函数。

var ds = new kendo.data.DataSource({
        type: 'odata',
        serverFiltering: true,
        serverPaging: true,
        pageSize: 10,
        transport: {
            read: {
                url: function () { return '{0}{1}'.format(_appRoot,_serviceUrl); },
                dataType: "json"
            }
            , parameterMap: function (data) {
                var d = kendo.data.transports.odata.parameterMap(data);
                delete d.$inlinecount;
                d.$count = true;

                if (d.$filter) {
                    // substringof('xYz',WorkUnitCode)  needs to 
                    // change to contains(WorkUnitCode,'06')
                    if (d.$filter.substring(0, 12) == 'substringof(') {
                        var parms = d.$filter.substring(12, d.$filter.length - 1).split(',');
                        d.$filter = 'contains({0},{1})'.format(parms[1],parms[0]);
                    }
                }

                return d;
            }
        },
        schema: {
            data: function (data) { return data.value; },
            total: function (data) { return data['@odata.count']; },
            model: _schemaModel
        }
        });

答案 4 :(得分:0)

我一直在多个自由文本搜索字符串上使用它:

paramMap.$filter = paramMap.$filter.replace(/substringof\(('.+?'),(.+?)\)/, "contains($2,$1)");

它允许用户过滤多个包含表达式。例如:

(Id gt 2 and (substringof('val1',FieldName) or substringof('val2',FieldName)))
// Translates to
(Id gt 2 and (contains(FieldName,'val1') or contains(FieldName,'val2')))

答案 5 :(得分:0)

@Ryan Mrachek回答的另一个改进示例:

// Let's use 'indexof' instead of 'substringof'
function substringofToIndexof(s) {
  s = s.substring(s.indexOf("("));
  s = s.substring(1, s.length - 1);
  const p = s.split(",");
  // Note: TypeScript syntax below
  return `indexof(${p[1]},${p[0]}) ge 0`;
}
...
parameterMap: (options, operation) => {
  const paramMap = kendo.data.transports.odata.parameterMap(options, operation);
  if (paramMap.$filter.startsWith("substringof")) {
    paramMap.$filter = substringofToIndexof(paramMap.$filter);
    return paramMap;
  }

Using Kendo UI With MVC4, WebAPI, OData And EF

Supporting OData Query Options in ASP.NET Web API 2

Using Filter Expressions in OData URIs