Asp.net web api 使用Kendoui网格的Odata v4包含过滤器
让contains筛选器与使用odata v4的asp.net web api web服务一起工作的最简单方法是什么 使用ODataV4的web服务似乎不再确认“substringof”函数,而希望使用“contains”函数 示例:使用网格中WorkUnitCode列上的Contains筛选器获取,并输入“xYz”。 子串(失败) GET需要什么才能使contains函数工作: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
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;
}