所以我的SqlDataSource的SelectQuery定义如下:
SELECT * FROM table
WHERE UserName IN (@EmployeesIn);
@EmployeesIn来自会话变量Session [“EmployeesIn”]。在Page_Load期间,我正在使用ArrayList成员并将结果放入字符串并设置会话变量:
string employeesIn = "";
foreach (string s in members)
{
employeesIn = employeesIn + "'" + s + "',";
}
employeesIn = employeesIn.TrimEnd(',');
Session["EmployeesIn"] = employeesIn;
将输出写入控制台我可以看到参数@EmployeesIn
的值 @EmployeesIn = 'bob', 'joe'
但是,我得到的结果为零......并且在从数据库级别进行监控后,我看到参数是以:
'''bob'',''joe'''
然后,如果我只传入一名员工,我会按预期从SQL中获取结果,并且参数正确传递为'bob'。我想这是.NET提供的针对SQL注入攻击的一些安全性,但是这有什么安全的方法呢?
答案 0 :(得分:2)
你应该绝对使用参数,而不是在SQL本身中包含值。您只需生成参数的名称,因此如果您有三个条目,则生成SQL:
SELECT * FROM table WHERE UserName IN (@p0, @p1, @p2)
然后从三个值中填入这三个参数。
// Or create the command earlier, of course
List<SqlParameter> parameters = new List<SqlParameter>();
StringBuilder inClause = new StringBuilder("(");
for (int i = 0; i < members.Count; i++)
{
string parameterName = "@p" + i;
inClause.Append(parameterName);
if (i != members.Count - 1)
{
inClause.Append(", ");
}
// Adjust data type as per schema
SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.NVarChar);
parameter.Value = members[i];
parameters.Add(parameter);
}
inClause.Append(")");
// Now use inClause in the SQL, and parameters in the command parameters
答案 1 :(得分:0)
SQL参数只能表示单个值,但您可以传入多个参数,例如:
var emps = members.Select( (e,i) => "@EMPLOYEE" + i).ToArray();
string sqlQuery = "SELECT * FROM table WHERE ";
sqlQuery+=string.Format("UserName IN ({0})", string.Join(",", emps));
//add SQL parameters used in query
for (int i = 0; i < members.Count; ++i)
{
parameters.Parameters.Add(new SqlParameter("@EMPLOYEE" + i, members[i]));
}
答案 2 :(得分:0)
我认为你有三种选择:
答案 3 :(得分:0)
更好的方法是使用参数列表来使用您的成员数组构建查询:
SELECT * FROM table
WHERE UserName IN (@EmployeesIn1, @EmployeesIn2, @EmployeesIn3, ... n);
然后遍历您的成员列表,根据需要添加参数。
答案 4 :(得分:0)
我注意到的第一件事就是你如何让你成为逗号清单。试试这个:
string employeesIn = string.Join(",", members.Select(x => string.format("'{0}'", x)).ToArray());
至于参数,您需要重新考虑您的方法。你看过表值参数了吗?