Идентификатор из нескольких частей System.Web.UI.HtmlControls.HtmlInputText не может быть привязан

У меня есть оператор вставки 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
}

person user1174548    schedule 22.03.2012    source источник
comment
Способ построения sSql кажется уязвимым для SQL Injection. Думали ли вы, что одним из ваших пользователей может быть Bobby Tables?   -  person Adam Mihalcin    schedule 22.03.2012
comment
Подготовленные операторы не помогают, но очень сильно, если вы не поместите каждое значение переменной в параметр. В этом случае, например, вы бы сказали VALUES(@DS0402Key, @VisitorLName) и добавили к команде параметр @DS0402Key так же, как @VisitorLName.   -  person cHao    schedule 22.03.2012


Ответы (1)


Если это действительно этот код, который выдает ошибку, я предполагаю, что, поскольку все ваши экранирование и цитирование перегружены, вы получите запрос вроде

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
}

Кроме того, найдите, где вы вставляете ключ в сеанс... и убедитесь, что вы не вставляете весь элемент управления (а не только его значение).

person cHao    schedule 22.03.2012
comment
Спасибо за ваш ответ, все хорошие предложения. Я попытался добавить Session[DS0402Key] в качестве параметра, и когда я ссылаюсь на него во вставке sql, VS2010 выдает ошибку, что он не существует в текущем контексте. Я попытался жестко закодировать значение DS0402Key вместе с @VisitorLName в sql, но все еще получаю исходную ошибку. - person user1174548; 22.03.2012
comment
Я также полностью удалил столбец DS0402Key, чтобы исключить, что это может быть причиной проблемы, но я все еще получаю исходную ошибку. - person user1174548; 22.03.2012
comment
Это не просто добавленный параметр, который отличается выше. Обратите внимание на строку SQL (в частности, я не строю ее специально, собирая вещи вместе; я позволяю параметрам делать свою работу). То, как вы делали вещи, все неправильно цитировало. Отсюда, скорее всего, ваша ошибка. - person cHao; 22.03.2012
comment
Я слышу, что вы говорите, и я буду использовать эту практику в будущем, но исходная ошибка все еще возникает, когда я использую оператор вставки с одним столбцом, например: sSql = INSERT INTO [camss].[dbo].[ tb_ds0402req] ( [lname] ) ЗНАЧЕНИЯ (@VisitorLName); - person user1174548; 22.03.2012
comment
Тогда изменения, которые я предложил, вероятно, сделаны неправильно. Если бы вы могли добавить свой код (в том виде, в каком он существует сейчас, исправлен, но все еще не работает) в свой ответ (добавьте его; не заменяйте то, что там есть!), или поместите его в pastebin и свяжите это, я мог бы помочь больше. Но на данный момент я должен предположить, что ошибка находится в другом месте. Код, как я написал, должен работать нормально. - person cHao; 22.03.2012
comment
Твое право. Я более внимательно изучил код, и он работает так, как вы предложили. Спасибо большое за вашу помощь. - person user1174548; 22.03.2012