Asp.net web api 使用Kendoui网格的Odata v4包含过滤器

Asp.net web api 使用Kendoui网格的Odata v4包含过滤器,asp.net-web-api,kendo-grid,odata,kendo-asp.net-mvc,odata-v4,Asp.net Web Api,Kendo Grid,Odata,Kendo Asp.net Mvc,Odata V4,让contains筛选器与使用odata v4的asp.net web api web服务一起工作的最简单方法是什么 使用ODataV4的web服务似乎不再确认“substringof”函数,而希望使用“contains”函数 示例:使用网格中WorkUnitCode列上的Contains筛选器获取,并输入“xYz”。 子串(失败) GET需要什么才能使contains函数工作: http://localhost:1486/odata/BillOfMaterials(2)/BillOfMater

让contains筛选器与使用odata v4的asp.net web api web服务一起工作的最简单方法是什么

使用ODataV4的web服务似乎不再确认“substringof”函数,而希望使用“contains”函数

示例:使用网格中WorkUnitCode列上的Contains筛选器获取,并输入“xYz”。 子串(失败)

GET需要什么才能使contains函数工作:

http://localhost:1486/odata/BillOfMaterials(2)/BillOfMaterialsItems?$format=json&$top=10&$filter=contains(WorkUnitCode,'xYz')&$count=true
我相信有两种方法可以解决这个问题,但不确定哪种方法更好,或者给出的解决方案如何可重用

方法1:截取请求并将其更改为使用带有反向参数的contains函数。
方法2:将子字符串功能添加到web api。

使用了更简单的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
        }
        });

这里是Ryan Mrachek答案的一个广义版本,使用regex replace

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;
}

@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)");

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

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')))

更新,因为不再需要任何调整来使其工作

从更改数据集类型

键入:“odata”

键入:“odata-v4”


我们应该做到这一点。示例源代码是@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;
  }


剑道并不真正支持v4。。。它似乎大部分是v3,其中有几个v4位。。。这是v4查询中允许的一组有效查询函数:
// 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;
  }