c#
  • sql
  • 2012-12-09 123 views 2 likes 
    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; 
        } 
    } 
    
    +0

    错误说的是什么? – Khan

    +0

    看起来你只希望返回一行,所以循环遍历行没有意义,但我怀疑这是错误的原因。哪条线引发异常,信息是什么? –

    +0

    你需要提供你得到的异常的细节,以获得有意义的答案。 – saille

    回答

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

    不过,也有与代码的几个其他问题,你可能不知道的:

    1. 你有一个SQL Injection漏洞,使您的 应用完全不安全。这是因为您有连接的SQL字符串 以进行查询而不是编写 parametized query

    2. 你应该养成在DataAdapters和DataTables上使用ADO.NET DataReader的习惯。或者更好的是,完全避免使用DataTables,因为它们是传统的 。使用Linq2Sql或Entity Framework作为您的数据访问层,您将编写少得多的代码。

    3. 你应该认真考虑使用ASP.NET Membersip API您的授权和角色等。如果你这样做,你的函数甚至不会被要求 - 你会这样写:Roles.IsUserInRole(sUserName,“用户”),以检查是否用户有一定的作用。

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

    +0

    完全删除'else'语句。 – Khan

    +0

    UPVOTE给你!因为我的声望不是15,所以我无法赞成。它的功能就像一个魅力,我可以通过我的会话发送给角色!谢谢! – scottO

    +0

    我明白了。感谢您提供更多信息。 – scottO

    0

    貌似连接字符串无效:

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

    应该是:

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

    注意,报价在初始目录值逃过一劫。如果这不是问题,请发布您的例外情况。

    +0

    代码看起来更像是他为了示例而替换了db名称。如果它是你建议的代码不会编译的。 – saille

    +0

    是的,我刚刚评论过这个样本。谢谢你的意见。 – scottO

    0

    变化

    string match; 
    

    string match = null; 
    

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

    相关问题