2017-02-24 23 views
-3

Ich verwende derzeit ein asp.net Webformular, um Daten aus einer Datenbank in mssql zu ziehen. Ich habe drei Tabellen (tOptions, tModel, tOptions_Model) und die Datenfelder sind (OptionsID, Optionen, ModelID, Model). Wenn Sie eines der Modelle aus der Dropdownliste auswählen, sendet das Formular eine SQL-Abfrage, um alle Optionen dieses Modells abzurufen. Wenn ich eines der Modelle aus der Dropdown-Liste auswähle, ist dies der Fehler, der empfangen wird:Korrekte Syntax für SQL-Abfrage in C#

Eine Ausnahme vom Typ 'System.Data.SqlClient.SqlException' ist in System.Data.dll aber aufgetreten wurde nicht im Benutzercode behandelt

Weitere Informationen: Falsche Syntax in der Nähe von '3' (die 3 stellt das Modell in der Dropdown-Liste ausgewählt, so wäre es das dritte Element in der ddl). Meine Frage ist, ist dies der richtige Weg, um alle Optionen basierend auf dem ausgewählten Modell zu greifen?

public partial class ModelsAndOptions : System.Web.UI.Page 
{ 
    private static System.Data.SqlClient.SqlConnection conn; 
    private static SqlDataSourceCommandEventArgs comm; 
    private static SqlDataReader reader; 


    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      OpenConnection(); 
     } 
    } 

    protected void ddlModel_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     int optionsID; 
     string options; 
     ListItem optionsItem; 
     // clear the listbox just in case something is already inside it. 
     lbxOptions.Items.Clear(); 

     string result = ("SELECT Options, OptionsID FROM tOptions WHERE ID = '('" + ddlModel.SelectedValue + "')'"); 


     SqlCommand comm = new SqlCommand(result, conn); 

     try 
     { 
      reader.Close(); 
     } catch (Exception ex) 
     { 

     } 
     //use reader obj to execute query 
     reader = comm.ExecuteReader(); 

     // iterate through dataset by each line 
     while (reader.Read()) 
     { 
      // stores primary key of options 
      optionsID = reader.GetInt32(0); 
      // stores name 
      options = reader.GetString(1); 
      // creates a list item with text of both the primary key and the name 
      optionsItem = new ListItem(options, optionsID.ToString()); 
      // add items to the listbox 
      lbxOptions.Items.Add(optionsItem); 
     } 
    } 

    private void OpenConnection() 
    { 
     System.Configuration.ConnectionStringSettings strConn; 

     strConn = ReadConnectionString(); 

      conn = new System.Data.SqlClient.SqlConnection(strConn.ConnectionString); 



     try 
     { 
      conn.Open(); 
     } 
     catch (Exception ex) 
     { 
      Response.Write(ex.Message); 
     } 

    } 
    private System.Configuration.ConnectionStringSettings ReadConnectionString() 
    { 
     //string to store the path 
     String strPath; 
     strPath = HttpContext.Current.Request.ApplicationPath + "/Web.config"; 

     //object that points to web.config file 
     System.Configuration.Configuration rootWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(strPath); 

     System.Configuration.ConnectionStringSettings connString = null; 

     // if the connection string is working, then set the object to equal the connection string located inside the web.config file 
     if (rootWebConfig.ConnectionStrings.ConnectionStrings.Count > 0) 
     { 
      connString = rootWebConfig.ConnectionStrings.ConnectionStrings["kroegedlConnectionString"]; 
     } 

     // return the connection string setting obj 
     return connString; 
    } 

    protected void btnAddOne_Click(object sender, EventArgs e) 
    { 
     lbxChosenOptions.Items.Add(lbxOptions.SelectedItem); 
     lbxOptions.Items.Remove(lbxOptions.SelectedItem); 
    } 
} 
+2

SQL-Injektionsalarm !!! Ihr Code ist weit offen für sql injection attack. Sie müssen parametrisierte Abfragen verwenden, bevor Bobby-Tabellen aufgerufen werden. http://bobby-tables.com/ –

+1

Ihr Code hat auch eine Reihe anderer Probleme hier. Sie verfügen nicht über die richtigen Verbindungs- und Befehlsobjekte, die Ihren Verbindungspool zerstören. Du hast auch, was ich einen Versuch/Squelch nenne, was ein Versuch ist zu fangen, aber der Haken macht nichts. Dies ist ein Anti-Pattern, das schlimmer ist, als den Fehler überhaupt nicht zu erfassen. –

+0

Für das vorliegende Problem müssen Sie in Datenbindung suchen. Sie müssen Ergebnismengen wie diese nicht durchlaufen und die Dropdown-Felder manuell ausfüllen. –

Antwort

2

Zu viele Sünden begangen

// Extract method: do not cram everything into single IndexChanged 
private void CoreAddOptions() { 
    // Do not open a global connection 
    // Wrap IDisposable into using 
    using (SqlConnection conn = new SqlConnection(ConnectionString)) { 
    conn.Open(); 

    // Make Sql Readable 
    // Make Sql paramterized 
    string sql = 
     @"select Options, 
       OptionsID 
      from tOptions 
      where Id = @prm_Id"; 

    // Wrap IDisposable into using 
    using (SqlCommand comm = new SqlCommand(sql, conn)) { 
     // Do not hardcode SQL but use parameters 
     comm.Parameters.AddWithValue("@prm_Id", ddlModel.SelectedValue); 

     // Wrap IDisposable into using 
     using (var reader = comm.ExecuteReader()) { 
     while (reader.Read()) { 
      // Use Convert instead of Get + ToString 
      var optionsItem = new ListItem(
      Convert.ToString(reader[0]), 
      Convert.ToString(reader[1])); 

      lbxOptions.Items.Add(optionsItem); 
     } 
     } 
    } 
    } 
} 

Dann

protected void ddlModel_SelectedIndexChanged(object sender, EventArgs e) { 
    CoreAddOptions();  
} 
0

eine gespeicherte Prozedur erstellen und validierte Parameter übergeben. Dies mildert die SQL-Injection und ermöglicht es Ihnen, Ihren Code einfacher zu testen.

Umschließen Sie alle Ressourcen in einer using-Anweisung, um sicherzustellen, dass sie entsorgt werden.

Verwandte Themen