C# c中的字符串格式属性#

C# c中的字符串格式属性#,c#,mysql,string,format,C#,Mysql,String,Format,我在ASP.NETC#和MySQL数据库中工作 我一直收到一个错误: 索引(从零开始)必须大于或等于零且小于 参数列表的大小 我的代码: string sql = String.Format(@" UPDATE `doTable` "); sql += String.Format(" SET Active = {0} "); sql += String.Format(" WHERE ID = {1}; ", Active.ToString(), ID.ToString()); 如果尝试此操作,

我在ASP.NETC#和MySQL数据库中工作

我一直收到一个错误:

索引(从零开始)必须大于或等于零且小于 参数列表的大小

我的代码:

string sql = String.Format(@" UPDATE `doTable` ");
sql += String.Format(" SET Active = {0} ");
sql += String.Format(" WHERE ID = {1}; ", Active.ToString(), ID.ToString());
如果尝试此操作,代码将正常工作,有什么区别

string sql = String.Format(@"UPDATE `doTable` SET 
                                     Active = {0}
                                     WHERE ID = {1}; ",
                                     Active.ToString(),
                                     ID.ToString());

你能帮我解决这个问题吗?

那行的问题

sql += String.Format(" SET Active = {0} ");
您为
String.Format
声明了索引组件,但从未添加其格式字符串组件。但在你的第二个例子中,你做到了。每一条语句都是独立的。这就是为什么这一行会抛出异常,但您的第二个代码部分不会

来自文件

A 如果参数说明符 指定对象列表边界之外的项

但是不要用这种方式! 你应该经常使用。这种类型的字符串连接对攻击是开放的


我强烈怀疑您的
ID
应该是数字类型,而不是基于名称的字符。

这一行的问题

sql += String.Format(" SET Active = {0} ");
您为
String.Format
声明了索引组件,但从未添加其格式字符串组件。但在你的第二个例子中,你做到了。每一条语句都是独立的。这就是为什么这一行会抛出异常,但您的第二个代码部分不会

来自文件

A 如果参数说明符 指定对象列表边界之外的项

但是不要用这种方式! 你应该经常使用。这种类型的字符串连接对攻击是开放的


我强烈怀疑您的
ID
应该是数字类型,而不是基于名称的字符。

您在两个不同的字符串中定义了两个参数。 将其更改为:

string sql = String.Format(@" UPDATE `doTable` ");
sql += String.Format(" SET Active = {0} ", Active.ToString());
sql += String.Format(" WHERE ID = {0}; ", ID.ToString());

您正在两个不同的字符串中定义两个参数。 将其更改为:

string sql = String.Format(@" UPDATE `doTable` ");
sql += String.Format(" SET Active = {0} ", Active.ToString());
sql += String.Format(" WHERE ID = {0}; ", ID.ToString());

如果您确实希望以这种方式构建您的查询,您应该修改代码,使其如下所示:

string sql = String.Format(@" UPDATE `doTable` ");
sql += String.Format(" SET Active = {0} ", Active.ToString());
sql += String.Format(" WHERE ID = {0}; ",  ID.ToString());

但这是一个坏主意。考虑使用<强> Sql命令参数< /强>:

如果你真的想用这种方式构建YOR查询,你应该修改你的代码是这样的:

string sql = String.Format(@" UPDATE `doTable` ");
sql += String.Format(" SET Active = {0} ", Active.ToString());
sql += String.Format(" WHERE ID = {0}; ",  ID.ToString());

但这是一个坏主意。考虑使用<强> Sql命令参数>:

,您应该总是提供尽可能多的参数作为最大占位符值+1。< /P> 代码中的第二行包含占位符

{0}
,但未提供值作为参数,因此软件无法完成字符串

在第二个示例中,您提供了两个占位符
{0}
{1}
以及两个参数(
Active.ToString()
ID.ToString()
),因此两个占位符都可以由一个参数替换


您还可以提供比占位符更多的参数(如代码的第三行),但这很少有意义,因为不会使用额外的值。

您应该始终提供与最大占位符值+1一样多的参数

代码中的第二行包含占位符
{0}
,但未提供值作为参数,因此软件无法完成字符串

在第二个示例中,您提供了两个占位符
{0}
{1}
以及两个参数(
Active.ToString()
ID.ToString()
),因此两个占位符都可以由一个参数替换


您还可以提供比占位符更多的参数(如代码的第三行),但这几乎没有意义,因为不会使用额外的值。

不要使用String.Format生成查询。这对sql注入是开放的,您应该使用
SqlCommand.Parameters
。此外,根据区域性的不同,使用数据时间类型和十进制数的ToString()可能会有很多问题

string sql = @"UPDATE [doTable] 
                  SET Active = @Active
                WHERE ID = @ID";

using (SqlCommand cmd = new SqlCommand(sql)) {
  cmd.Parameters.AddWithValue("@ID", ID);
  cmd.Parameters.AddWithValue("@Active", Active);

不要使用String.Format生成查询。这对sql注入是开放的,您应该使用
SqlCommand.Parameters
。此外,根据区域性的不同,使用数据时间类型和十进制数的ToString()可能会有很多问题

string sql = @"UPDATE [doTable] 
                  SET Active = @Active
                WHERE ID = @ID";

using (SqlCommand cmd = new SqlCommand(sql)) {
  cmd.Parameters.AddWithValue("@ID", ID);
  cmd.Parameters.AddWithValue("@Active", Active);

这是因为在构建sql stringtry时,您使用的是不带任何参数的
string.format
:改为:
sql+=string.format(“SET Active={0}”,Active.ToString())
etc对于这两个stringsDon't home brew参数化语句,使用一个为您执行此操作的
MySqlCommand
。正如Alex所说-
顽皮,淘气的
构建sql注入倾向的字符串之所以如此,是因为您在构建sql字符串时使用的是
string.format
而没有任何参数尝试:改为:
sql+=string.format(“SET Active={0}”,Active.ToString())MySqlCommand
。正如Alex所说-
顽皮,顽皮
要构建易于sql注入的Strings,应该是
“WHERE ID={0};”
(请注意
0
)@DmitryBychenko您说得对!我已经编辑了我的帖子。应该是
“WHERE ID={0};”
(请注意
0
)@DmitryBychenko你说得对!我已经编辑了我的帖子。
SqlCommand
?然后呢?对不起,我不太明白为什么OP选择这个作为答案。(无意冒犯)
SqlCommand
?然后呢?对不起,我不太明白为什么OP选择这个作为答案。(无意冒犯)