2012-04-22 48 views
1

我很有興趣在我的ASP.net應用程序中添加參數化sql查詢。我見過一些關於避免SQL注入的好文章。SQLCommand在單獨的類中使用時使用參數化sql查詢

string sql = string.Format("INSERT INTO [UserData] (Username, Password, Role, Membership, DateOfReg) VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)"); 
     SqlCommand cmd = new SqlCommand(sql, conn); 
     try 
     { 
     cmd.Parameters.AddWithValue("Username", usernameTB.Text); 
     cmd.Parameters.AddWithValue("Password", passwordTB.Text); 
     cmd.Parameters.AddWithValue("Role", roleTB.Text); 
     cmd.Parameters.AddWithValue("Membership", membershipTB.Text); 
     cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text); 

     conn.Open(); 
     cmd.ExecuteNonQuery(); 
     conn.Close(); 

find the Reference

但是這種方式對我來說並不實用,因爲我對夫婦的DB連接到單獨的類,因爲我有重用。

public class DBconnection{  
    public int insertQuery(String query) { 



      int affectedRowCount = 0; 
      SqlConnection conn = null; 
      try{ 

       conn = new SqlConnection("Server=localhost;Database=master;UID=sa;PWD=sa;"); 
       SqlCommand cmd = new SqlCommand(query, conn); 
       cmd.CommandType = CommandType.Text; 

       conn.Open(); 
       affectedRowCount = cmd.ExecuteNonQuery(); 
       conn.Close();   

      } catch (Exception e){ 

         String error = e.Message; 

      } 

      return affectedRowCount; 
    } 
} 

因此,我只使用波紋管代碼部分來調用上面的類並將值插入到數據庫中。

String SQLQuery1 = insert into Article values('" + Txtname.Text + "','" + TxtNo.Text + "','" + Txtdescription.Text + "' ,0)"); 
DBconnection dbConn = new DBconnection(); 
     SqlDataReader Dr = dbConn.insertQuery(SQLQuery1); 

請幫我使用Parameterize sqlString來避免我Sql Injection。 要使用@name,@ No和@description而不使用文本框輸入。

回答

1

這樣做是完全合理的,但要讓你的類回調(lambda/delegate)來獲取參數。這是一類的靜態方法,它是通過各種重載實例方法叫做:

private static int SqlExec(string ConnectionString, string StoredProcName, Action<SqlCommand> AddParameters, Action<SqlCommand> PostExec) 
     { 
      int ret; 
      using (var cn = new SqlConnection(ConnectionString)) 
      using (var cmd = new SqlCommand(StoredProcName, cn)) 
      { 
       cn.Open(); 
       cmd.CommandType = CommandType.StoredProcedure; 

       if (AddParameters != null) 
       { 
        AddParameters(cmd); 
       } 

       ret = cmd.ExecuteNonQuery(); 

       if (PostExec != null) 
       { 
        PostExec(cmd); 
       } 
      } 
      return ret; 
     } 

然後,使用示例:

public void Save() 
    { 
     Data.Connect().Exec("Project_Update", Cm => 
     { 
      Cm.Parameters.AddWithValue("@ProjectID", ID); 
      Cm.Parameters.AddWithValue("@PrimaryApplicantID", PrimaryApplicant.IdOrDBNull()); 
      Cm.Parameters.AddWithValue("@SecondaryApplicantID", SecondaryApplicant.IdOrDBNull()); 
      Cm.Parameters.AddWithValue("@ProjectName", ProjectName.ToDBValue()); 
     }); 
    } 

也有可能與非存儲過程調用來做到這一點。

在你的情況下,它看起來像:

DBconnection.InsertQuery(
    "INSERT INTO [UserData] 
     (Username, Password, Role, Membership, DateOfReg) 
     VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)" 
    ,cmd => { 
       cmd.Parameters.AddWithValue("Username", usernameTB.Text); 
       cmd.Parameters.AddWithValue("Password", passwordTB.Text); 
       cmd.Parameters.AddWithValue("Role", roleTB.Text); 
       cmd.Parameters.AddWithValue("Membership", membershipTB.Text); 
       cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text); 
      } 
); 

這使你的所有數據庫的東西在一起,你想要的方式,並讓DBConnection的保持它的內部隔離。

+0

謝謝。這是爲我工作,這是我尋找。 :) – devan 2012-04-23 05:04:38

1

如何編寫特定的InsertQuery方法而不是通用的InsertQuery()方法?

例如:

public void AddNewUser(User u) 
{ 
    var query = "insert Users (name, password) values (@0, @1)"; 
    SqlCommand cmd = new SqlCommand(query, conn); 
     try 
     { 
     cmd.Parameters.AddWithValue("@0", u.UserName); 
     cmd.Parameters.AddWithValue("@1", u.Password); 
     } 
} 

這在這個其他類所有SQL邏輯之中,而不是調用類需要知道如何構造查詢等

它的優點也使得您的代碼更具可讀性,因爲您將AddUserUpdateUserChangePassword視爲方法調用,並且無需在此刻讀取SQL來嘗試猜測程序中發生了什麼。

無論其如果你打算做這樣的事情,你應該檢查出一些MicroORMs,我個人最喜歡的是PetaPoco(或NuGet version

PetaPoco和其他類似的大規模和小巧玲瓏將讓你做像這樣:

database.Insert(u); 

其中u是一個用戶對象,映射到您的數據庫的表。它使用ADO.NET並確保使用SQL參數。

0

我會建議使用LINQ to SQL,其中automatically parametrizes everything

問:LINQ to SQL如何防止SQL注入攻擊?

答:SQL注入一直是通過連接用戶輸入形成的傳統SQL查詢的重大風險。 LINQ to SQL通過在查詢中使用SqlParameter避免了這種注入。用戶輸入變爲參數值。這種方法可防止從客戶輸入中使用惡意命令。

您可以insert, update and delete從使用DataContext(在你的項目中單擊鼠標右鍵添加一個新項目,並添加LINQ to SQL Classes模板,然後使用服務器資源管理器將對象添加到它)以直接的方式SQL數據庫。

我還沒有在一段時間這個工作,但我相信你的代碼看起來有點像這樣:

UserData user = new UserData(); 

user.Username = ...; 
user.Password = ...; 
user.Role = ...; 
user.Membership = ...; 
user.DateOfReg = ...; 

db.UserDatas.InsertOnSubmit(user); 
db.SubmitChanges(); 

當你調用的SubmitChanges,LINQ to SQL的自動生成和執行SQL命令,它必須將更改傳回數據庫。

EDIT1:

作爲一個額外的音符,從數據庫中檢索現有的項目,你可以這樣做:

var user = (from i in db.UserDatas 
      where i.UserName == "devan" 
      select i).Single(); 

哦,因爲是我的標準政策,回答時關於數據庫與登錄信息的問題,我必須懇求你,爲神的愛和所有的神聖,salt and hash your users' passwords

相關問題