我正在尝试获取返回值并且它一直给我一个错误。 我试图通过发送用户名验证用户名后抓取“roleid” - 我无法弄清楚我做错了什么?
public string ValidateRole(string sUsername)
{
string matchstring = "SELECT roleid FROM tblUserRoles WHERE UserName='" + sUsername +"'";
SqlCommand cmd = new SqlCommand(matchstring);
cmd.Connection = new SqlConnection("Data Source=(local);Initial Catalog=samplename;Integrated Security=True");
cmd.Connection.Open();
cmd.CommandType = CommandType.Text;
SqlDataAdapter sda = new SqlDataAdapter();
DataTable dt = new DataTable();
sda.SelectCommand = cmd;
sda.Fill(dt);
string match;
if (dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
match = row["roleid"].ToString();
return match;
}
}
else
{
match = "fail";
return match;
}
}
答案 0 :(得分:6)
您看到的“并非所有代码路径都返回值”错误是编译器错误,而不是运行时错误,因此问题在于您的C#代码不正确。
在这种情况下,因为你在foreach循环中有一个return语句,并且编译器不够聪明,如果数据表中没有行,你的代码就会沿着'else'路径向下移动。即编译器无法看到'If(true)'分支将始终返回一个值。
最佳做法是在函数末尾始终有一个return语句,并初始化变量('match'未初始化)。如果你中途返回,你的代码也不太可读。
最简单的解决方法是:
public string ValidateRole(string sUsername)
{
string matchstring = "SELECT roleid FROM tblUserRoles WHERE UserName='" + sUsername +"'";
SqlCommand cmd = new SqlCommand(matchstring);
cmd.Connection = new SqlConnection("Data Source=(local);Initial Catalog=samplename;Integrated Security=True");
cmd.Connection.Open();
cmd.CommandType = CommandType.Text;
SqlDataAdapter sda = new SqlDataAdapter();
DataTable dt = new DataTable();
sda.SelectCommand = cmd;
sda.Fill(dt);
string match = "fail";
if (dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
match = row["roleid"].ToString();
return match;
}
}
return "fail";
}
但是,您可能不了解的代码还有其他几个问题:
您有一个SQL Injection漏洞,可以让您的 应用程序完全不安全。这是因为你有 连接SQL字符串以进行查询而不是编写 parametized query
你应养成在DataAdapters和DataTables上使用ADO.NET DataReader的习惯。或者更好,完全避免使用DataTables 他们是遗产。使用Linq2Sql或Entity Framework获取数据 访问层,您将编写更少的代码。
您应该认真考虑使用ASP.NET Membersip API作为授权和角色等。如果您这样做,甚至不需要您的功能 - 您只需编写:Roles.IsUserInRole(sUserName,“User) “)检查用户是否担任某个角色。
当您使用实现IDisposable的资源(如SQLConnection)时,您应该将其用于using() {} block,以便您始终尽快释放资源。
答案 1 :(得分:0)
看起来连接字符串无效:
SqlConnection("Data Source=(local);Initial Catalog="mydatabase";Integrated Security=True");
应该是:
SqlConnection("Data Source=(local);Initial Catalog=\"mydatabase\";Integrated Security=True");
请注意,引号在初始目录值中转义。如果这不是问题,请发布您的例外。
答案 2 :(得分:0)
更改
string match;
到
string match = null;
如果foreach
从未找到匹配项,则变量match
永远不会被实例化。编译错误试图告诉你这个。