C# “多部分标识符”;System.Web.UI.HtmlControls.HtmlInputText“;无法约束

C# “多部分标识符”;System.Web.UI.HtmlControls.HtmlInputText“;无法约束,c#,asp.net,sql-server,sqlcommand,C#,Asp.net,Sql Server,Sqlcommand,我有一个insert sql语句,它使用SqlCommand功能来防止sql注入,但它给出了一个错误:无法绑定多部分标识符“System.Web.UI.HtmlControls.HtmlInputText”。我使用相同的SqlCommand功能更新相同的表,没有问题,但是,下面这个简单的插入给出了错误。有人能帮忙吗 sSql = "INSERT INTO [camss].[dbo].[tb_ds0402req] ( [ds0402_key] ,[lname] ) " + "VALU

我有一个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
}

如果确实是这段代码抛出了错误,我的猜测是,因为转义和引用都被顶起了,所以最终会出现如下查询

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()
…中的返回值,该返回值返回控件类型的完全限定名

(在不加引号的情况下键入
@VisitorLName
不会出现错误,因为
@
是C#的一种转义标识符的方法,这样您就可以使用关键字作为变量名等。就C#而言,您刚才说的是……
+VisitorLName+

还要注意的是,构建SQL字符串的方式并没有利用参数,而参数是阻止SQL注入的主要功能,可以简化SQL构建,从而启动!如果要使用参数,请将它们用于不是表名或其他内容的每个值。(对于表/数据库/架构/等名称,您可以自行决定。您不能使用参数来代替这些名称。请阅读:您很容易再次受到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
}

另外,找到将密钥插入会话的位置…并确保没有插入整个控件(而不仅仅是它的值)。

构建
sSql
的方式似乎容易受到SQL注入的影响。您是否考虑过这可能是您的一个用户?准备好的语句没有多大帮助,但除非您将每个变量值都放入一个参数中。例如,在本例中,您可以说
值(@DS0402Key,@VisitorLName)
,并以与
@VisitorLName
相同的方式将参数
@DS0402Key
添加到命令中。感谢您的回复,所有好的建议。我尝试添加会话[“DS0402Key”]作为参数,当我在insert sql中引用它时,VS2010给出一个错误,即它在当前上下文中不存在。我尝试在sql中硬编码DS0402Key的值和@VisitorLName,但仍然收到原始错误。我还完全删除了DS0402Key列,只是为了排除它可能导致问题,但仍然收到原始错误。与上面不同的不仅仅是添加的参数。请注意SQL字符串(特别是,我不是通过将内容集中在一起来构建它,而是让参数来完成工作)。你做事的方式,一切都是错的。这就是你的错误很可能来自的地方。我听到了你说的话,这是我将继续使用的一种做法,但当我使用一个带有一列的insert语句时,仍然会出现原始错误,如:sSql=“insert INTO[camss].[dbo].[tb_ds0402req]([lname])值(@VisitorLName)”;那么,我建议的更改可能没有正确执行。如果你能把你的代码添加到你的答案上(添加它,不要替换它!),或者把它放在一个粘贴箱中并链接它,我可以提供更多帮助。但在这一点上,我不得不假设错误在别处。我写的代码应该可以正常工作。