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ステートメントを置き、変数を初期化することです('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インジェクションの脆弱性があります。これは、パラメータ化されたクエリを作成するのではなく、SQL文字列を連結してクエリを作成したためです 。

  2. DataAdaptersおよびDataTablesではなくADO.NETDataReaderを使用する習慣を身に付ける必要があります。または、DataTablesはレガシーであるため、完全に回避することをお勧めします。データアクセス層にLinq2SqlまたはEntityFrameworkを使用すると、作成するコードがはるかに少なくなります。

  3. 承認や役割などにASP.NETMembersipAPIを使用することを真剣に検討する必要があります。そうすれば、関数は必要ありません。次のように記述します。Roles.IsUserInRole(sUserName、 "User")ユーザーは特定の役割を担っています。

  4. SQLConnectionなどのIDisposableを実装するリソースを使用する場合は、その使用を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");

初期カタログ値で引用符がエスケープされていることに注意してください。これが問題ではない場合は、例外を投稿してください。

于 2012-12-09T23:11:42.570 に答える
0

変化する

string match;

string match = null;

一致するものが見つからない場合foreach、変数matchはインスタンス化されません。コンパイルエラーはこれを伝えようとしています。

于 2012-12-09T23:25:46.910 に答える