我需要实现一个休息端点,该端点应接受查询作为输入。如下所示:
api.com/api/v1/users/(registrationDate eq'2018-07-01')AND((高度gt 160)或(高度lt 68))
这种查询将不需要任何联接。实体的所有字段都可以包含在查询中。
我想到的第一件事是将查询输入直接转换为sql查询的where子句,
Dictionary<string, string> Operators = new Dictionary<string, string>
{
{ " eq ", " = " },
{ " ne ", " != " },
{ " gt ", " > " },
{ " gte ", " >= " },
{ " lt ", " < " },
{ " lte ", " <= " }
};
public string SQLify<T>(string query)
{
if (query == null)
{
return $"SELECT * FROM [{typeof(T).Name}]";
}
foreach (var op in Operators)
{
query = query.Replace(op.Key, op.Value);
}
return $"SELECT * FROM [{typeof(T).Name}] WHERE ({query})";
}
并像这样使用它:
query = queryService.SQLify<User>(query);
var users = DbContext.Users.SqlQuery(query);
但是您可能会猜到,我非常担心它可能带来的安全隐患。我实际上尝试编写一些验证方法,检查方括号的嵌套,并检查所提到的字段实际上是类T
的成员,但我确定它们提供的安全性将不足。
在这种情况下最好的方法是什么?
答案 0 :(得分:1)
也许带有OData端点的WebAPI应该可以解决问题。
答案 1 :(得分:1)
您应该构建端点,以便它对参数使用参数化查询,并将其他元素(表,运算符和列)列入白名单。
您已经为操作员提供了白名单,但是您应该从头开始构建SQL,并丢弃(或错误删除)与白名单不符的内容,而不是替换现有字符串。
如果有数据授权(并非每个人都可以从端点访问所有数据),则还需要在端点中考虑这一点。