我是
Asp.net的新手,我刚刚开始上课.我最近创建了一个类,它将为我处理大多数SQL查询,这样我就不必重复创建所有文件的新连接.
我创建的方法之一将SQL查询作为参数并返回结果.我知道我应该使用参数化查询来避免sql注入.我的问题是,当我将查询作为字符串参数传递时,我该怎么做?
public static DataTable sqlDataTable(string sql) { using (sqlConnection conn = new sqlConnection(DatabaseConnectionString)) { sqlCommand cmd = new sqlCommand(sql,conn); cmd.Connection.Open(); DataTable TempTable = new DataTable(); TempTable.Load(cmd.ExecuteReader()); return TempTable; } }
DataTable dt = new DataTable(); dt = sqlComm.sqlDataTable("SELECT * FROM Users WHERE UserName='" + login.Text + "' and Password='" + password.Text + "'"); if (dt.Rows.Count > 0) { // do something if the query returns rows }
这有效,但仍然容易受到注射吗?有没有办法可以将变量作为参数传递给字符串?我知道如果我为查询创建一个新的sqlCommand对象并使用Parameters.AddWithValue,我可以这样做,但我希望所有的sql命令都在单独的类中.
解决方法
This works but would still be vulnerable to injections right?
I know that I should be using parameterized queries to avoid sql injections.
哦,绝对是的.
My question is,how can I do this when I’m passing the query as a string parameter?
您根本不应该将查询作为字符串参数传递.相反,您应该将查询作为包含占位符的字符串参数和这些占位符的值传递:
public static DataTable sqlDataTable(string sql,IDictionary<string,object> values) { using (sqlConnection conn = new sqlConnection(DatabaseConnectionString)) using (sqlCommand cmd = conn.CreateCommand()) { conn.Open(); cmd.CommandText = sql; foreach (KeyValuePair<string,object> item in values) { cmd.Parameters.AddWithValue("@" + item.Key,item.Value); } DataTable table = new DataTable(); using (var reader = cmd.ExecuteReader()) { table.Load(reader); return table; } } }
然后像这样使用你的函数:
DataTable dt = sqlComm.sqlDataTable( "SELECT * FROM Users WHERE UserName = @UserName AND Password = @Password",new Dictionary<string,object> { { "UserName",login.Text },{ "Password",password.Text },} ); if (dt.Rows.Count > 0) { // do something if the query returns rows }