Ciao e benvenuto nel forum!
Quando sbagli username e password, il metodo dr.Read() restituirà false, perché il SqlCommand non ha ottenuto alcuna riga come risultato.
Infatti, nella tua SELECT imponi che username e password corrispondono, ma questo non produrrà risultati se i dati sono sbagliati.
Come conseguenza, il tuo blocco else non andrà mai in esecuzione, perché si trova innestato nel while, all'interno del quale il programma non entra mai dato che dr.Read() era false.
Secondo me, dovresti semplicemente
conteggiare il numero di righe ottenute. Se sono 0, vuol dire che il login è fallito.
string username=Request.Form["txtuser"];
string password=Request.Form["txtpass"];
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconn"].ToString())) {
cn.Open();
using (SqlCommand sql = new SqlCommand("SELECT COUNT(*) from utenti where username=@username AND password=@password",cn)){
sql.Parameters.AddWithValue("@username",username);
sql.Parameters.AddWithValue("@password", password);
int conteggio = Convert.ToInt32(sql.ExecuteScalar());
if (conteggio == 0){
errore_accesso.Text = "I dati di login non sono corretti, riprova";
} else {
FormsAuthentication.RedirectFromLoginPage(username, false);
}
}
}
Alcune considerazioni:
- Bravo per aver usato i SqlParameters, ti messo al riparo dalla Sql injection;
- Se usi dei controlli server come l'asp:Textbox, puoi recuperare l'input dell'utente dalla loro proprietà Text, anziché leggerla dal Request.Form;
- Non usare la sessione per tracciare gli utenti autenticati. E' un meccanismo obsoleto. Qui trovi maggiori informazioni su un approccio alternativo basato su cookie di autenticazione.
http://forum.aspitalia.com/forum/post/402579/Best-Pratice-SESSIONE-UTENTE.aspx - Nell'esempio di codice ho usato blocchi using che servono a chiudere e distruggere automaticamente sia il SqlCommand che la SqlConnection, anche se si dovesse verificare un errore.
In generale, andrebbe usato con tutti gli oggetti che implementano IDisposable, ovvero che possiedono un metodo .Dispose() - Il metodo ExecuteScalar del SqlCommand che ho usato nell'esempio, restituisce un valore scalare, preso dalla prima colonna della prima riga del risultato. La SELECT così modificata (con un COUNT) ora restituisce sempre un risultato: il conteggio delle righe trovate.
ciao,
Moreno
Modificato da BrightSoul il 21 agosto 2015 18.46 -