2017-03-03 2 views
1

Ich schreibe einige serverseitige Validierung in asp.net für Login-Seite.Variable existiert nicht im aktuellen Kontext C#

Jetzt komme ich von einer PHP-Perspektive "schreibe es von Grund auf" und ich lerne und kämpfe mit einigen dieser asp.net-Konzepte, denen ich nicht bewusst bin.

Ich versuche, einen Benutzernamen und eine Passwort-Variable auf "gültig" zu setzen, wenn die Eingabe gültig ist, und ich versuche, diese Variablen zu verwenden, um mit der Anmeldung fortzufahren.

Ich bin mir auch nicht sicher, ob dies der richtige Weg ist, Dinge zu tun.

protected void loginbutton_Click(object sender, EventArgs e) 
    { 
     string UsernameRegex = "[a-zA-Z]+"; 
     string PasswordRegex = "[a-zA-Z0-9]+"; 

     if (!Regex.IsMatch(usernametextbox.Text, UsernameRegex)) 
     { 
      string UsernameCheck = "valid"; 
     } 
     else 
     { 
      string UsernameCheck = "invalid"; 
     } 

     if (!Regex.IsMatch(passwordtextbox.Text, PasswordRegex)) 
     { 
      string PasswordCheck = "valid"; 
     } 
     else 
     { 
      string PasswordCheck = "invalid"; 
     } 


     if(UsernameCheck = "valid") //i will include password here after i solved the problem 
     { 
      //do something 
     } 
      SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
      conn.Open(); 
      string checkuser = "select count(*) from Users where Username = @username and Password = @password"; 

      SqlCommand com = new SqlCommand(checkuser, conn); 
      com.Parameters.Add("@username", SqlDbType.NVarChar).Value = usernametextbox.Text; 
      com.Parameters.Add("@password", SqlDbType.NVarChar).Value = passwordtextbox.Text; 

      int temp = Convert.ToInt32(com.ExecuteScalar().ToString()); 

      if (temp > 0) 
      { 
       Response.Redirect("Cars.aspx"); 
      } 
      else 
      { 
       loginfaillabel.Text = "Your Username or Password doesn't match our records"; 
      } 
     } 

Hilfe und Feedback ist willkommen.

+0

Hier ist, wie Sie tun, würde es in [Web Forms] (https://msdn.microsoft.com/en-us/library /a0z2h4sw.aspx). Hth. – EdSF

+2

Mögliches Duplikat von [Variable Umfang Verwirrung in C#] (http://stackoverflow.com/questions/1196941/variable-scope-confusion-in-c-sharp) – Brandon

+1

Auch '==' in 'if (BenutzernameCheck =" gültig ")' usw. – EdSF

Antwort

3

Ok, hier viel Feedback.

  1. Verwenden Sie booleans, keine Zeichenfolgen! Ich habe sie für dich ersetzt. Das Hauptproblem hier war, was Umfang hatte. Sie könnten die Variable außerhalb des if deklarieren und das Problem lösen, aber besser einen booleschen Wert verwenden und den if-Block einfach loswerden, wenn er lesbarer wird.
  2. Umwickeln Sie immer Ihre Ado.Net-Typen, die IDisposable in using Blöcke implementiert. Auf diese Weise, wenn der Code auf eine Ausnahme stößt, ist Ihre Verbindung noch geschlossen (eine gute Sache)
  3. Keine Notwendigkeit, count in Ihrer SQL-Anweisung zu tun, einfach zurückgeben 1. Wenn es einen Benutzer gibt, erhalten Sie andernfalls ein Ergebnis.
  4. Niemals Passwörter im Klartext speichern! Ich habe das nicht berührt, das liegt an dir. Es gibt viele geeignete Passwort-Hashing-Algorithmen zur Auswahl, wie pbkdf2, bcrypt und scrypt, um einige der allgemein akzeptierten sicheren Algorithmen zu nennen.
  5. Sind Sie sicher, dass der Benutzername Unicode ist? Wenn nicht, ändern Sie den Parametertyp in VarChar in Ihrem SqlParameter Typ.

Modified Code

protected void loginbutton_Click(object sender, EventArgs e) 
{ 
    string UsernameRegex = "[a-zA-Z]+"; 
    string PasswordRegex = "[a-zA-Z0-9]+"; 

    boolean isUsernameValid = Regex.IsMatch(usernametextbox.Text, UsernameRegex) 
    boolean isPasswordValid = Regex.IsMatch(passwordtextbox.Text, PasswordRegex); 


    if(!isUsernameValid || !isPasswordValid) //i will include password here after i solved the problem 
    { 
     //do something 
    } 
    else 
    { 
     const string checkuser = "SELECT 1 FROM Users WHERE Username = @username and Password = @password"; 

     using(SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString)) 
     using(SqlCommand com = new SqlCommand(checkuser, conn)) 
     { 
      conn.Open(); 

      com.Parameters.Add("@username", SqlDbType.NVarChar).Value = usernametextbox.Text; 
      com.Parameters.Add("@password", SqlDbType.NVarChar).Value = passwordtextbox.Text; 

      object temp = com.ExecuteScalar(); 

      // I do not remember if it is null or System.DbNull.Value that is returned if nothing is returned 
      // you will have to test it 
      var didUserMatch = temp == null || temp == System.DbNull.Value ? false : true; 

      if (didUserMatch) 
      { 
       Response.Redirect("Cars.aspx"); 
      } 
      else 
      { 
       loginfaillabel.Text = "Your Username or Password doesn't match our records"; 
      } 
     } 
    } 
} 
+1

Vielen Dank, viele nützliche Feedback, ich habe viele nützliche Erkenntnisse dank Ihnen gewonnen. –

+0

@ReeceCostello - froh, dass ich helfen konnte. – Igor

2

Ich sehe 3 Probleme mit Ihrem Code:

  1. Sie verwenden Strings für Sie Variable * Prüfen, sollten Sie booleans verwenden.

  2. In der Zeile if(UsernameCheck = "valid") Sie "valid" zu UsernameCheck den Wert tatsächlich zuweisen, wenn Sie für die Gleichstellung testen möchten, verwenden Sie if(UsernameCheck == "valid")

  3. Das Problem, das Sie haben tatsächlich aufgrund der Variablen Umfang ist. Sie deklarieren die Variablen UsernameCheck und PasswordCheck innerhalb der if/else-Anweisungen, dh sie existieren nur innerhalb des if/else, wenn die Codeausführung das if/else existiert, die Variable nicht mehr existiert, versuchen Sie diesen Code (und lesen Sie a etwas mehr über C#):

    protected void loginbutton_Click (object sender, EventArgse) { Zeichenfolge UsernameRegex = "[a-zA-Z] +"; Zeichenfolge PasswordRegex = "[a-zA-Z0-9] +";

    bool UsernameCheck = false; // better name for this is isUsernameValie 
    
        if (!Regex.IsMatch(usernametextbox.Text, UsernameRegex)) 
        { 
         UsernameCheck = true; 
        } 
        else 
        { 
         UsernameCheck = false; 
        } 
    
        bool PasswordCheck = false;// better name for this is isPasswordValid 
        if (!Regex.IsMatch(passwordtextbox.Text, PasswordRegex)) 
        { 
         PasswordCheck = true; 
        } 
        else 
        { 
         PasswordCheck = false; 
        } 
    
    
        if (UsernameCheck == true) //i will include password here after i solved the problem 
        { 
         //do something 
        } 
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
        conn.Open(); 
        string checkuser = "select count(*) from Users where Username = @username and Password = @password"; 
    
        SqlCommand com = new SqlCommand(checkuser, conn); 
        com.Parameters.Add("@username", SqlDbType.NVarChar).Value = usernametextbox.Text; 
        com.Parameters.Add("@password", SqlDbType.NVarChar).Value = passwordtextbox.Text; 
    
        int temp = Convert.ToInt32(com.ExecuteScalar().ToString()); 
    
        if (temp > 0) 
        { 
         Response.Redirect("Cars.aspx"); 
        } 
        else 
        { 
         loginfaillabel.Text = "Your Username or Password doesn't match our records"; 
        } 
    } 
    
0

you need check variable and method scops.

-Code ein wenig Bearbeitung

protected void loginbutton_Click(object sender, EventArgs e) 
    { 
     string UsernameRegex = "[a-zA-Z]+"; 
     string PasswordRegex = "[a-zA-Z0-9]+"; 

     var userName = usernametextbox.Text; 
     var password = passwordtextbox.Text; 

     if (!Regex.IsMatch(userName, UsernameRegex)) 
     { 
      // do something 
      return; // There is no need to go on 
     } 

     if(!Regex.IsMatch(password, PasswordRegex)) 
     { 
      // do something 
      return; // There is no need to go on 
     } 

     //If we can come here, we can go DB 

     // To be dispose when the job is done 
     using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString)) 
     { 

      try 
      { 
       // To be dispose when the job is done 
       using (SqlCommand com = new SqlCommand(checkuser, conn)) 
       { 
        conn.Open(); 
        string checkuser = "select count(*) from Users where Username = @username and Password = @password"; 
        com.Parameters.Add("@username", SqlDbType.NVarChar).Value = userName; 
        com.Parameters.Add("@password", SqlDbType.NVarChar).Value = password; 
        int temp = Convert.ToInt32(com.ExecuteScalar().ToString()); 
        if (temp > 0) 
        { 
         Response.Redirect("Cars.aspx"); 
        } 
        else 
        { 
         loginfaillabel.Text = "Your Username or Password doesn't match our records"; 
        } 
       } 
      } 
      catch (Exception ex) 
      { 

       // you can handle error. maybe logs 
      } 
     } 
    } 
0

Während Sie Dinge tun können, basierend auf den anderen Antworten, IMHO, nutzen die in Web Forms Validation gebaut braucht zuerst. Wenn es zu kurz kommt, dann etwas anderes tun.

triviales Beispiel:

  • foo.aspx

    <p>Username (Alphabetic only, no spaces):<br /> 
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> 
        <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox1" Display="Dynamic" ErrorMessage="Username is required"></asp:RequiredFieldValidator> 
        <asp:RegularExpressionValidator ID="NameValidator" runat="server" ControlToValidate="TextBox1" Display="Dynamic" ErrorMessage="Invalid - Alaphabetic only" ValidationExpression="[a-zA-Z]+" EnableClientScript="True"></asp:RegularExpressionValidator> 
    </p> 
    <p>Password (Alphanumeric only, no spaces):<br /> 
        <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox> 
        <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="TextBox2" Display="Dynamic" ErrorMessage="Password is required"></asp:RequiredFieldValidator> 
        <asp:RegularExpressionValidator ID="PwdValidator" runat="server" ControlToValidate="TextBox2" Display="Dynamic" ErrorMessage="Invalid -Alphanumeric Only" ValidationExpression="[\w]+" EnableClientScript="True"></asp:RegularExpressionValidator> 
    </p> 
    <p> 
        <asp:Button ID="Button1" runat="server" OnClick="BtnSubmit" Text="Login" /> 
    </p> 
    

    EnableClientScript ist True standardmäßig. Sie können es auf False setzen, um Dinge zu testen oder zu sehen, was ohne Client-seitige Validierung passiert (siehe serverseitige Validierung in Aktion).

  • foo.aspx.cs (auch bekannt als "Code hinter")

    public partial class foo: Page 
    { 
        protected void Page_Load(object sender, EventArgs e) 
        { 
    
        } 
    
        protected void BtnSubmit(object sender, EventArgs e) 
        { 
         if (Page.IsValid) 
         { 
          //Do what you need to do only if IsValid which is the server-side validation check 
         } 
        } 
    } 
    
Verwandte Themen