C# 在单独的类中使用SQLCommand时使用参数化sql查询
我对在ASP.net应用程序中添加参数化sql查询很感兴趣。我看过一些关于避免SQL注入的好文章C# 在单独的类中使用SQLCommand时使用参数化sql查询,c#,asp.net,sql-injection,code-reuse,C#,Asp.net,Sql Injection,Code Reuse,我对在ASP.net应用程序中添加参数化sql查询很感兴趣。我看过一些关于避免SQL注入的好文章 string sql = string.Format("INSERT INTO [UserData] (Username, Password, Role, Membership, DateOfReg) VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)"); SqlCommand cmd = new SqlCom
string sql = string.Format("INSERT INTO [UserData] (Username, Password, Role, Membership, DateOfReg) VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)");
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
cmd.Parameters.AddWithValue("Username", usernameTB.Text);
cmd.Parameters.AddWithValue("Password", passwordTB.Text);
cmd.Parameters.AddWithValue("Role", roleTB.Text);
cmd.Parameters.AddWithValue("Membership", membershipTB.Text);
cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
然而,这种方法对我没有用处,因为我将DB连接耦合到单独的类,因为我已经重用了它
public class DBconnection{
public int insertQuery(String query) {
int affectedRowCount = 0;
SqlConnection conn = null;
try{
conn = new SqlConnection("Server=localhost;Database=master;UID=sa;PWD=sa;");
SqlCommand cmd = new SqlCommand( query, conn );
cmd.CommandType = CommandType.Text;
conn.Open( );
affectedRowCount = cmd.ExecuteNonQuery( );
conn.Close( );
} catch ( Exception e ){
String error = e.Message;
}
return affectedRowCount;
}
}
因此,我只使用下面的代码部分来调用上面的类并向DB插入值
String SQLQuery1 = insert into Article values('" + Txtname.Text + "','" + TxtNo.Text + "','" + Txtdescription.Text + "' ,0)");
DBconnection dbConn = new DBconnection();
SqlDataReader Dr = dbConn.insertQuery(SQLQuery1);
请帮助我使用参数化sqlString以避免Sql注入。
在不使用文本框输入的情况下使用@name、@No和@description。如何代替通用的InsertQuery()方法编写特定的InsertQuery方法 例如:
public void AddNewUser(User u)
{
var query = "insert Users (name, password) values (@0, @1)";
SqlCommand cmd = new SqlCommand(query, conn);
try
{
cmd.Parameters.AddWithValue("@0", u.UserName);
cmd.Parameters.AddWithValue("@1", u.Password);
}
}
这样做的好处是,所有SQL逻辑都位于另一个类中,而调用类需要知道如何构造查询等
它还使您的代码更具可读性,因为您可以在方法调用中看到AddUser
或UpdateUser
或ChangePassword
,而不必在此时读取SQL来尝试猜测程序中发生了什么
然而如果你要做这样的事情,你应该去看看一些MicroORMs,我个人最喜欢的是(或)
PetaPoco和其他像Massive和Dapper这样的公司会让你做如下事情:
database.Insert(u);
其中u是映射到数据库表的用户对象。它使用ADO.NET并确保使用SQL参数。我建议使用LINQ to SQL,这是一个很好的例子 如何保护LINQ到SQL免受SQL注入攻击 答:SQL注入对于通过连接用户输入形成的传统SQL查询来说是一个重大风险。LINQtoSQL通过在查询中使用SqlParameter避免了这种注入。用户输入将转换为参数值。此方法可防止从客户输入中使用恶意命令 您可以使用
DataContext
(右键单击项目以添加新项并添加LINQ to SQL class
模板,然后使用服务器资源管理器向其添加对象)以简单的方式从SQL数据库中删除数据
我已经有一段时间没有使用它了,但我相信您的代码会有点像这样:
UserData user = new UserData();
user.Username = ...;
user.Password = ...;
user.Role = ...;
user.Membership = ...;
user.DateOfReg = ...;
db.UserDatas.InsertOnSubmit(user);
db.SubmitChanges();
当您调用SubmitChanges时,LINQtoSQL自动生成并执行SQL命令,它必须将您的更改传输回数据库
Edit1:
作为补充说明,要从数据库检索现有项,可以执行以下操作:
var user = (from i in db.UserDatas
where i.UserName == "devan"
select i).Single();
哦,这是我回答关于数据库登录信息的问题时的标准策略,我必须恳求你,看在上帝的份上,以及所有神圣的事情上。这样做是完全合理的,但是让你的类回调(lambda/委托)来获取参数。这是由各种重载实例方法调用的类中的静态方法:
private static int SqlExec(string ConnectionString, string StoredProcName, Action<SqlCommand> AddParameters, Action<SqlCommand> PostExec)
{
int ret;
using (var cn = new SqlConnection(ConnectionString))
using (var cmd = new SqlCommand(StoredProcName, cn))
{
cn.Open();
cmd.CommandType = CommandType.StoredProcedure;
if (AddParameters != null)
{
AddParameters(cmd);
}
ret = cmd.ExecuteNonQuery();
if (PostExec != null)
{
PostExec(cmd);
}
}
return ret;
}
对于非存储过程调用也可以这样做
在您的情况下,它看起来像:
DBconnection.InsertQuery(
"INSERT INTO [UserData]
(Username, Password, Role, Membership, DateOfReg)
VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)"
,cmd => {
cmd.Parameters.AddWithValue("Username", usernameTB.Text);
cmd.Parameters.AddWithValue("Password", passwordTB.Text);
cmd.Parameters.AddWithValue("Role", roleTB.Text);
cmd.Parameters.AddWithValue("Membership", membershipTB.Text);
cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text);
}
);
这将按照您希望的方式将所有数据库内容放在一起,并使数据库连接保持其内部隔离。谢谢。这是我的工作,这是我在寻找的。:)
DBconnection.InsertQuery(
"INSERT INTO [UserData]
(Username, Password, Role, Membership, DateOfReg)
VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)"
,cmd => {
cmd.Parameters.AddWithValue("Username", usernameTB.Text);
cmd.Parameters.AddWithValue("Password", passwordTB.Text);
cmd.Parameters.AddWithValue("Role", roleTB.Text);
cmd.Parameters.AddWithValue("Membership", membershipTB.Text);
cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text);
}
);