#c# #asp.net #.net #asp.net-mvc #asp.net-core
#c# #asp.net #.net #asp.net-mvc #asp.net-ядро
Вопрос:
У нас есть требование, согласно которому клиент может фильтровать записи на основе определенных условий.
Ниже приведен пример условия фильтра, которое я получаю в контроллере
[
{
"Field":"BANKNAME",
"Operator":"=",
"Value":"35",
"ConditionOperator":"OR",
"DField":"N"
},
{
"Field":"BANKNAME",
"Operator":"=",
"Value":"15",
"ConditionOperator":"AND",
"DField":"N"
},
{
"Field":"PTLOCATION",
"Operator":"=",
"Value":"261",
"ConditionOperator":" ",
"DField":"Y"
]
На основе условия фильтра мы генерируем SQL-запрос, ниже приведен код, который мы пробовали
var FilterCondition = JsonConvert.DeserializeObject<List<RptFilterCondition>>(filter);
string filterCondition = string.Empty;
var lstFilterCondition = FilterCondition.Where(a => a.DField == "N").ToList();
for (int i = 0; i < lstFilterCondition.Count; i )
{
if (i == 0 amp;amp; FilterCondition.Count == 1)
{
filterCondition = " custom.CustomeFieldName ='" lstFilterCondition[i].Field "' and custom.FIELDVALUE " lstFilterCondition[i].Operator "'" lstFilterCondition[i].Value "' ";
}
else if (i == 0 amp;amp; !isanycondition)
{
filterCondition = " (custom.CustomeFieldName ='" lstFilterCondition[i].Field "' and custom.FIELDVALUE " lstFilterCondition[i].Operator "'" lstFilterCondition[i].Value "' )" lstFilterCondition[i].ConditionOperator;
}
else if (i == FilterCondition.Count - 1)
{
filterCondition = " (custom.CustomeFieldName='" lstFilterCondition[i].Field "' and custom.FIELDVALUE " lstFilterCondition[i].Operator "'" lstFilterCondition[i].Value "' )";
}
else
{
filterCondition = " (custom.CustomeFieldName='" lstFilterCondition[i].Field "' and custom.FIELDVALUE" lstFilterCondition[i].Operator "'" lstFilterCondition[i].Value "' )" lstFilterCondition[i].ConditionOperator;
}
}
return filterCondition;
Ниже сгенерировано условие фильтра
(custom.CustomeFieldName ='BANKNAME' and custom.FIELDVALUE ='35') OR
(custom.CustomeFieldName='BANKNAME' and custom.FIELDVALUE='15')
and (PTLOCATION = 261)
Ниже ожидается, что для одинаковых имен полей должна быть круглая скобка
((custom.CustomeFieldName ='BANKNAME' and custom.FIELDVALUE ='35') OR
(custom.CustomeFieldName='BANKNAME' and custom.FIELDVALUE='15'))
and (PTLOCATION = 261)
Комментарии:
1. Это похоже на ожидающую атаки sql-инъекции
2. @00110001 можете ли вы предложить мне лучший способ сделать с вышеуказанной логикой, я попытаюсь реализовать то же самое
3.
custom.CustomeFieldName
custom.FIELDVALUE
? Итак, у вас есть таблица пользовательских полей, где каждое поле хранится в виде строки? Означает ли это, что вам нужноand exists(select 1 from ....)
обходить каждый тест?
Ответ №1:
Как упоминалось в комментарии, код уязвим для SQL-инъекции.
Одной из альтернатив является использование ORM, например EF, и написать свой собственный «движок» для перевода из пользовательской модели запросов в LINQ — https://docs.microsoft.com/en-us/ef/core/querying /
Более простым вариантом может быть использование OData, который поддерживает пользовательские запросы «из коробки» с подключением к EF — https://docs.microsoft.com/en-us/odata/webapi/getting-started , https://docs.microsoft.com/en-us/odata/client/query-options