2017-02-24 139 views
-3

我目前使用的是asp.net webform從數據庫中取出數據在mssql中。我有三個表(tOptions,tModel,tOptions_Model),數據字段是(OptionsID,Options,ModelID,Model)。表單所做的是,當您從下拉列表中選擇一個模型時,它將發送一個sql查詢以獲取與該模型對應的所有選項。我遇到的錯誤是當您從下拉列表中選擇一個模型時,這是收到的錯誤:C#中SQL查詢的正確語法

在System.Data.dll中發生類型'System.Data.SqlClient.SqlException'的異常但不在用戶代碼中處理

附加信息:「3」附近的語法不正確(3代表在下拉列表中選擇的模型,因此它將是ddl中的第三項)。我的問題是,這是根據所選模型獲取所有選項的正確方法嗎?

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注入警報!!!你的代碼對sql注入攻擊是開放的。您需要在bobby表訪問之前使用參數化查詢。 http://bobby-tables.com/ –

+1

你的代碼也有一些其他的問題。你沒有正確地處理連接和命令對象,這會殺死你的連接池。你也有我所說的嘗試/壓制,這是一個嘗試抓住但抓住什麼都不做。這是一種反模式,比起首先沒有捕捉到錯誤更糟糕。 –

+0

對於手頭的問題,您需要查看數據綁定。您不需要像這樣遍歷結果集並手動填充下拉框。 –

回答

2

太多的罪COMMITED

// 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); 
     } 
     } 
    } 
    } 
} 

然後

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

創建一個存儲過程,並通過驗證的參數傳遞給它。 這可以減輕SQL注入的負擔,並允許您更輕鬆地測試代碼。

將所有資源封裝在using語句中以確保它們已被丟棄。