c#
  • sql
  • 2012-12-09 180 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永遠不會被實例化。編譯錯誤試圖告訴你這一點。

    相關問題