我用c#创建了一个应用程序,在我的认证接口中,我有一个测试控件,我想知道配置文件用户。
我的数据库包含名为user
的表,其中包含 4 列
(id_user,name ,mail, profile)
这是我的代码
public string profil_user(string login)
{
SqlConnection conn = new database().connect_user();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select profile from user where name = '" + login + "';";
SqlDataReader s = cmd.ExecuteReader();
if (s.Read())
{
return ( s.GetString(3));
}
else{return ("false"); }
}
但我有一个例外s.GetString(3)
系统。索引超出范围:索引在数组的边界之外
您只选择一个字段 (profile
(,但您尝试在此处选择第 4 个字段(索引 3(:
return ( s.GetString(3));
除了返回s.GetString(0)
我强烈建议您:
- 使用参数化 SQL -始终执行此操作,以防止 SQL 注入攻击,使代码更具可读性,并防止意外的文本转换问题
- 如果未找到配置文件,则抛出异常或返回
null
,而不是返回字符串"false"> - 对一次性内容(如
SqlCommand
、SqlConnection
和SqlDataReader
(使用using
语句,以确保适当地清理资源 - 开始遵循 .NET 命名约定,使代码更具惯用 性
所以像这样:
public string GetUserProfile(string login)
{
string sql = select profile from user where name = @login";
// I assume Connect() returns an *open* connection?
using (var conn = new Database().Connect())
{
using (var command = new SqlCommand(sql, conn))
{
command.Parameters.Add("@login", SqlDbType.NVarChar).Value = login;
using (var reader = command.ExecuteReader())
{
// If it's an error (code failure) for there to be no matching profile,
// you may want to throw an exception instead.
return s.Read() ? s.GetString(0) : null;
}
}
}
}
所以你想要第四行,而不是你尝试用s.GetString(3)
访问的第四列:
int rowNum = 0;
while(s.Read())
{
if(++rowNum == 4)
{
return s.GetString(0);
}
}
return "false";
但是,当您不使用Order By
时访问第四行有点奇怪。您还应该只返回具有正确 sql 查询的所需行。
如果您在此处使用字符串连接,您也对 sql 注入开放:
cmd.CommandText = "select profile from user where name = '" + login + "';";
使用 sql 参数:
cmd.CommandText = "select profile from user where name = @login";
cmd.Parameters.Add("@login", SqlDbType.VarChar).Value = login;
有 4 列而不是行
好的,所以你想要第四列。你为什么不改用这个名字?
由于您只选择profile
列(第四列(,因此您可以简单地使用GetString(0)
.但您也可以选择所有列,然后使用GetOrdinal
确定正确的索引:
int profileColumnIndex = s.GetOrdinal("profile");
return s.GetString(profileColumnIndex);
如果您不控制查询,或者将来可能会更改查询,这将非常有用。
您只选择 1 个字段,因此索引 3 超出范围。使用参数也非常重要。尝试:
cmd.CommandText = "select profile from user where name = @login;";
cmd.Parameters.Add("@login, SqlDbType.NVarChar).Value = login;
SqlDataReader s = cmd.ExecuteReader();
while (s.Read())
{
return s[0].ToString();
}
SqlDataReader.GetString 的参数应该是列索引。您只选择一列,因此会出现异常。
因为您的选择列表中没有所有字段
将 SQL 更改为:
select id_user,name ,mail, profile from user where name = '" + login + "';