我有一个insert sql语句,它使用SqlCommand功能进行sql注入预防,但它给出了错误:无法绑定多部分标识符“System.Web.UI.HtmlControls.HtmlInputText”。我使用相同的SqlCommand功能来更新同一个表而没有任何问题,但是,下面这个简单的插入会给出错误。有人可以帮忙吗?
sSql = "INSERT INTO [camss].[dbo].[tb_ds0402req] ( [ds0402_key] ,[lname] ) " +
"VALUES (" + Session["DS0402Key"] + "," + @VisitorLName + ");";
try
{
using (SqlCommand cmd = new SqlCommand(sSql, conn))
{
cmd.Parameters.AddWithValue("@VisitorLName", VisitorLName.Value);
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
//error handling code
}
答案 0 :(得分:2)
如果这个代码确实抛出错误,我的猜测就是因为你的转义和引用都被搞砸了,你最终会得到一个像
这样的查询INSERT INTO [camss].[dbo].[tb_ds0402req] ( [ds0402_key] ,[lname] )
VALUES (whatever your key is unquoted!, System.Web.UI.HtmlControls.HtmlInputText)
(假设VisitorLName
是HtmlInputText
控件)。您没有添加字符串"@VisitorLName"
,因为它不在引号中 - 您正在插入VisitorLName.ToString()
的返回值...其中,AFAIK返回类型的完全限定名称控制。
(在没有引号的情况下捕获@VisitorLName
时没有收到错误,因为@
是C#转义标识符的方式,因此您可以使用关键字作为变量名称等。就C#而言,你刚才说...... + VisitorLName +
......。)
另请注意,您正在构建SQL字符串的方式,您没有利用参数,这是阻止SQL注入的主要功能 - 并简化您的SQL构建,启动!如果您要使用参数,请将它们用于不是表名或其他任何值的每个值。 (对于表/数据库/模式/ etc等名称,你是独立的。你不能使用参数代替那些。阅读:你再次容易受到SQL注入。所以不要那样做,除非你有到!)
为了解决问题,请更改代码,使其显示为
sSql = "INSERT INTO [camss].[dbo].[tb_ds0402req] ( [ds0402_key] ,[lname] ) " +
"VALUES (@DS0402Key, @VisitorLName)";
try
{
using (SqlCommand cmd = new SqlCommand(sSql, conn))
{
cmd.Parameters.AddWithValue("@DS0402Key", Session["DS0402Key"]);
cmd.Parameters.AddWithValue("@VisitorLName", VisitorLName.Value);
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
//error handling code
}
此外,找到你将密钥插入会话的位置......并确保你没有插入一个完整的控件(而不仅仅是它的值)。