結合論壇用戶操作談asp.net表單驗證(上) 有了前面的知識,現在我們要進入實戰。做過asp的朋友都知道表單驗證是個比較頭疼的問題,有經 驗的Web程序員有這么一句話,那就是客戶端不相信服務器端,服務器端不相信客戶端。什么意思呢,就 是說做表單驗證時服務器端程序不能假定客戶端程序是正確的而不加檢測,這樣如果客戶端關閉 javascript就可能造成出錯,而如果只做服務器端檢測,那么需要提交到服務器端再返回,那么效率會大 打折扣,并且對于用戶極不方便。所以只能客戶端和服務器端做兩次驗證。現在asp.net提供了新的表單 驗證機制,下面我將結合實例簡單講一下,想要了解asp.net提供的幾個驗證webcontrol的詳細資料,可 以參照我的asp+初級教程。 在講表單驗證以前,先做點準備工作。前面談到用asp.net開發需要轉換編程思維,也就是用面向對 象的思想去考慮問題,bbs對象我們已經構造好了,現在讓我們來看一下一個論壇系統中另外一個很重要 的對象:用戶。可以說,論壇系統的主體是用戶,沒有用戶那也就談不上什么論壇了,所以圍繞用戶的操 作很多,比如說添加/刪除用戶,查詢/修改用戶資料等等,有些論壇還有積分機制,根據用戶登錄次數或 發言多少來決定積分,已表明該用戶的活躍程度。那么,我們應該如何來構造論壇用戶這個對象呢?看看 下面的類定義: namespace MyOwnClass { using System; using MyOwnClass ; using System.Data.SQL ; using System.Web.Util ; //////////////////////////////////////////////////////////////////// // // Class Name : BBSUser // // Description: 論壇用戶類,構造一個論壇用戶對象 // // date: 2000/02/03 // /// //////////////////////////////////////////////////////////////// public class BBSUser { //新建枚舉類型,創建用戶方式,創建還是修改 public enum CreateType { Create = 0 , Modify } //私有成員變量 private int m_intID ; //用戶ID private string m_strUserName ; //用戶名 private string m_strPassword ; //密碼 private string m_strEmail ; //用戶email private string m_strHomepage ; //個人主頁 private string m_strSignature ; //簽名 //屬性,全部只讀 public int ID { get { return m_intID ; } } public string UserName { get { return m_strUserName ; } } public string Password { get { return m_strPassword ; } } public string Email { get { return m_strEmail ; } } public string Homepage { get { return m_strHomepage ; } } public string Signature { get { return m_strSignature ; } } //構造函數 public BBSUser() { // // TODO: Add Constructor Logic here // m_strUserName = "" ; m_strPassword = "" ; m_strEmail = "" ; m_strHomepage = "" ; m_strSignature = "" ; } //根據用戶名查詢用戶資料 public bool GetUser(string a_strUserName) { //如果用戶名中包含單引號則拋出一個異常 if (a_strUserName.IndexOf("'") != -1) { throw(new Exception("用戶名包含非法字符")) ; } bool bExists = false ; MyConnection myConn = new MyConnection() ; try { myConn.Open() ; SQLCommand myCommand = new SQLCommand() ; myCommand.ActiveConnection = myConn ; myCommand.CommandText = "select * from BBSUser where UserName='" + a_strUserName + "'"; SQLDataReader myReader ; myCommand.Execute(out myReader) ;
if (myReader.Read()) { m_intID = (int)myReader["ID"] ; m_strUserName = myReader["UserName"].ToString() ; m_strPassword = myReader["password"].ToString() ; m_strEmail = myReader["Email"].ToString() ; m_strHomepage = myReader["Homepage"].ToString() ; m_strSignature = myReader["Signature"].ToString() ; bExists = true ; } else { bExists = false ; } myReader.Close() ; myConn.Close() ;
} catch(SQLException e) //如果出現異常 { throw(new Exception("數據庫異常:" + e.Message)) ;
} //返回結果 return bExists ; } //重載,根據用戶ID查找用戶 public bool GetUser(int a_intUserID) { bool bExists = false ; MyConnection myConn = new MyConnection() ; try { myConn.Open() ; SQLCommand myCommand = new SQLCommand() ; myCommand.ActiveConnection = myConn ; myCommand.CommandText = "select * from BBSUser where id=" + a_intUserID.ToString() ; SQLDataReader myReader ; myCommand.Execute(out myReader) ;
if (myReader.Read()) { m_intID = (int)myReader["ID"] ; m_strUserName = myReader["UserName"].ToString() ; m_strPassword = myReader["password"].ToString() ; m_strEmail = myReader["Email"].ToString() ; m_strHomepage = myReader["Homepage"].ToString() ; m_strSignature = myReader["Signature"].ToString() ; bExists = true ; } else { bExists = false ; } myReader.Close() ; myConn.Close() ;
} catch(SQLException e) //如果出現異常 { throw(new Exception("數據庫異常:" + e.Message)) ;
} //返回結果 return bExists ; } //新建用戶 public void CreateUser(BBSUser.CreateType a_enumCreateType ,string a_strUserName , string a_strPassword , string a_strEmail , string a_strHomepage , string a_strSignature) { //監測參數有效性 if (a_strUserName.IndexOf("'") != -1 || a_strPassword.IndexOf("'") != -1 || a_strEmail.IndexOf("'") != -1 || a_strHomepage.IndexOf("'") != -1 || a_strSignature.IndexOf("'") != -1) { throw(new Exception("包含非法字符")) ; } try { MyOwnClass.MyConnection myConn = new MyConnection() ; SQLCommand myCmd = new SQLCommand() ; //判斷是新建用戶還是修改用戶資料 if (a_enumCreateType == BBSUser.CreateType.Create) { myCmd.CommandText = "insert into BBSUser(UserName , Password , Email , Homepage , Signature)" + "values('" + a_strUserName + "','" + a_strPassword + "','" + a_strEmail + "','" + a_strHomepage + "','" + a_strSignature + "')" ; } else { myCmd.CommandText = "update BBSUser set Email='" + a_strEmail + "' , Homepage='" + a_strHomepage + "' , Signature='" + a_strSignature + "' where username='" + a_strUserName + "'"; } myConn.Open() ; myCmd.ActiveConnection = myConn ; myCmd.ExecuteNonQuery() ; myConn.Close() ; } catch(SQLException exp) { throw(new Exception("數據庫出錯:" + exp.Message)) ; } } //取回密碼 public void GetPassword(string a_strUserName , string a_strEmail) { if (GetUser(a_strUserName) && m_strEmail == a_strEmail) { //發送Email System.Web.Util.MailMessage myMail = new MailMessage() ; myMail.From = "lyp@server1.domain" ; myMail.Subject = "取回您的密碼" ; myMail.Body = "請牢記您的密碼:" + m_strPassword ; myMail.To = a_strEmail ; SmtpMail.Send(myMail) ; } else { throw (new Exception("該用戶不存在")) ; } }
} } 通過前面的學習,你可能已經能夠看懂這個類定義的大部分內容,那些是成員變量,那些是屬性,那 些是方法都可以理解了,在這里需要解釋的只有以下兩部分內容,首先看這段代碼:
public enum CreateType { Create = 0 , Modify } 這段代碼的作用是創建BBSUser類的一個枚舉變量,寫過c程序的朋友很容易理解,建立這個枚舉變量 的作用是簡化記憶,用容易記憶的名稱代替值,比如上邊這個定義,當在方法CreateUser里作為第一個參 數時,BBSUser.CreateType.Create實際的值是0,代表這個方法的目的是創建用戶,而如果是 BBSUser.CreateType.Modify,則代表目的是修改用戶資料。顯而易見,用if (a_enumCreateType == BBSUser.CreateType.Create)這樣的語句比用if (a_intCreateTYpe == 1)更容易記憶,最大限度減少出 錯的可能。 另外一個要解釋的內容是:你可能已經注意到在類的定義中有兩個 GetUser方法的定義,其作用域和 返回值都相同,只是參數類型不同。沒錯,這種做法叫重載(override),是并且只能是面向對象程序語言 實現多態性的基本方法,那么這樣做有什么好處呢?就是根據參數不同由類自己決定應該調用那個正確的 方法,這樣講可能有些抽象,那么舉個例子來說吧,這個GetUser方法的作用是取得用戶資料,那么它可 以通過用戶名來取得資料,也可以通過用戶ID來取得,如果不用函數的重載,那么我們需要建兩個函數, 可能一個叫GetUserFromName(string a_strName) , 而另一個是GetUserFormID(int a_intID),在調用時 需要判斷一下決定調用那個方法,象這樣: if ( BBSUser.ID != "") { GetUserFromID(BBSUser.ID) ; } else if(BBSUser.Name != "") { GetUserFromName(BBSUser.Name) ; } 以上兩種方法孰優孰劣恐怕已經不用我說了吧。 好了,既然我們已經創建好BBSUser對象,下面就可以利用它來進行對用戶的操作了。
|