2

我正在尝试获取返回值,但它一直给我一个错误。我试图通过发送用户名来验证用户名后获取“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;
    }
}
4

3 回答 3

6

您看到的“并非所有代码路径都返回值”错误是编译器错误,而不是运行时错误,因此问题在于您的 C# 代码不正确。

在这种情况下,这是因为您在 foreach 循环中有一个 return 语句,并且编译器不够聪明,无法看到如果数据表中没有行,您的代码将沿着“else”路径前进。即编译器看不到'If (true)' 分支总是会返回一个值。

最佳做法是始终在函数末尾有一个 return 语句,并初始化变量(“匹配”未初始化)。如果您中途返回,您的代码的可读性也会降低。

最简单的解决方法是:

 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";

   }

但是,您可能不知道代码还有其他几个问题:

  1. 您有一个SQL 注入漏洞,使您的应用程序完全不安全。这是因为您已连接 SQL 字符串来进行查询,而不是编写 参数化查询

  2. 您应该养成使用ADO.NET DataReader而不是 DataAdapters 和 DataTables 的习惯。或者更好的是,完全避免使用 DataTables,因为它们是遗留的。为您的数据访问层使用 Linq2Sql 或实体框架,您将编写更少的代码。

  3. 您应该认真考虑为您的授权和角色等使用ASP.NET Membersip API。如果您这样做了,甚至不需要您的函数 - 您只需编写: Roles.IsUserInRole(sUserName, "User") 来检查是否用户处于特定角色。

  4. 当您使用实现 IDisposable 的资源(如 SQLConnection)时,您应该将其使用包装在using() {} 块中,以便始终尽快释放资源。

于 2012-12-09T23:26:08.620 回答
0

看起来连接字符串无效:

SqlConnection("Data Source=(local);Initial Catalog="mydatabase";Integrated Security=True");

应该:

SqlConnection("Data Source=(local);Initial Catalog=\"mydatabase\";Integrated Security=True");

请注意,引号在 Initial Catalog 值中进行了转义。如果这不是问题,请发布您的例外。

于 2012-12-09T23:11:42.570 回答
0

改变

string match;

string match = null;

如果foreach永远找不到匹配项,则该变量match永远不会被实例化。编译错误试图告诉你这一点。

于 2012-12-09T23:25:46.910 回答