程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> Effective C#原則39:使用.Net驗證

Effective C#原則39:使用.Net驗證

編輯:關於C#

用戶的輸入可能是多種多樣的:你必須在交互式的控件中盡可能的驗證輸入 。寫一些用戶輸入驗證可能很做作,而且也有出錯的可能,但還是很有必要的。 不能太相信用戶的輸入,用戶可能會輸入任何內容導致異常發生,進而進行SQL 注入式攻擊。我們不希望任何類似這樣的事情發生。你應該了解足夠的信息來懷 疑用戶的輸入。很好,每個人都應該這樣做,這也就是為什麼.Net框架已經擴展 了這樣的功能,你可以使用這些功能從而使自己的代碼編寫工作減到最小,因為 我們要對用戶輸入的每一塊數據都要進行驗證。

.Net框架提供了不同的 機制來驗證用戶的輸入,分別可以用在Web和Windows應用程序中。Web應用程序 應該在浏覽器上進行數據驗證,一般是使用JavaScript。一些驗證控件在HTML面 而中生成一些JS代碼,這對你的用戶來說是很有效的:在對每一項輸入時,他們 不用每次返回數據到服務上。這些Web控件是使用正則表達式的擴展功能來完成 對用戶輸入的驗證,這些驗證可以在頁面提交到服務器之間完成。即使如此,你 還是要在服務器上做一些額外的驗證,以免受到程序式的攻擊。Windows就用程 序使用不同的模式。用戶的輸入可以直接在應用程序中用C#代碼來驗證。所有的 Windows控件都是可驗證的,當你想通知用戶的非法輸入時。一般的模式是使用 屬性訪問時的異常來指示非法的輸入。UI控件捕獲這些異常然後顯示錯誤給用戶 。

你可以使用5個web控件來處理ASP.net應用程序中的大多數驗證任務。 這5個控件都是由屬性來控制這些要驗證的特殊的字段。 RequiredFieldValidator 強制用戶在給定字段中輸入一個值,RangeValidator 要求特殊的字段提供的值在給定范圍內,這個范圍可是一個數的大小,也可以是 一個字符串的長度。CompareValidator 可以讓你構造一個驗證規則來驗證表單 上兩個同的控件。這三個控件都很簡單。最後兩個控件提供了強大的功能,可以 讓你根據你想要求的方法進行驗證。RegularExpression 驗證使用與此同時表達 式來驗證用戶的輸入。如果與比較返回匹配,輸入的就是合法的。正則表達式是 很有用的語言。你可以為你所有的實際情況創建正則表達式。VS.net包含了一些 驗證的表達式,這可以幫助你開始學習它。這有一些幫助你學習更多正則表達式 的有用資料,而且我強烈鼓勵你學習它。但我不能跑題而不給你提供一些最常用 的構造。表5.1顯示了最常用的一些正則表達式元素,你可能會在你的應用程序 中用來驗證輸入:

表5.1 常用的正則表達式

構造含意

[a -z]匹配單個小寫字符。括號內的字符集中的任何字符與單個字符匹配。

\d任何數字。

^,$^表示串的開始, $表示結束。

\w匹配任何 單詞.這是[A-Za-z0-9]簡寫。

(?NamedGroup\d{4,16})顯示兩個不同的常 用元素,?NamedGroup 定義了一個特殊的變量來引用匹配。{4,16}匹配前面的構 造至少4次最多16次。這一模式匹配一個至少包含4個但不超過16個數字的字符串 。如果匹配存在,那麼結果會存儲在NamedGroup中以便後面使用。

(a|b|c)匹配a或b或c。 用堅線分開的是選擇操作:輸入的可是其中的任何一個 。

(?(NamedGroup)a|b) 可選的。這與C#裡的三元操作等效,也就是說, 如果NamedGroup 存在,匹配a,否則匹配b.

(譯注,關於正則表達式這裡 只是簡單的說明了一下。覺得作者在這裡寫正則表達式很是不倫不類,即不全也 不精。)

使用這些及正則表達式的構造,你可以發現你可以驗證用戶提交 給你的任何內容。如果正則表達式還不夠,你還可以通過從CustomValidator 派 生一個新在類添加你自己的驗證。這是一個不小的工作,而且我盡可能的避免它 。當你用C#寫了一服務器函數來驗證數據後,還要用ECMAscript寫一個客戶端的 驗證函數。我討厭同樣的事做兩遍,而且我也盡可能的避免用ECMAscript寫任何 內容,所以,我喜歡粘貼正則表達式式。

例如,這有一個正則表達式, 用於驗證US的電話號碼。它接受區號用括號括起來的,或者沒有括號的,然後就 是區號和號碼之間的空格,交換局號(exchange ),以及號碼。區號和交換局號 之間的橫線也是可選的:

((\(\s*\d{3}\s*\))|(\d{3}))-?\s*\d{3}\s*-\s*\d{4}

通過查驗每一個組的表達式,這樣的邏輯是很清楚的:

((\(\s*\d{3}\s*\))|(\d{3}))-?

這和區號匹配,它充許(XXX)或者XXX的形式,其中 XXX是三個數字。任何在數字周圍的空白字符是充許的。最後兩個字符,-和?, 是許可但不要求一個橫線。

剩下的部份用於匹配電話的XXX-XXXX部份。\s匹配任意的空白,\d{3}匹配三個數字,\s*-\s*匹配一個圍繞在數字邊上的空白字符。最後,\d{4}精確匹配4個數字。

windows驗證工作方法小有不同,你 沒有預先的驗證分析。相反,你要寫一個事件句柄到 System.Windows.Forms.Control.Validating事件上,或者,如果你創建了你自 己的控件,重載OnValidating方法(參見原則35)。下面是一個標准的方法:

private void textBoxName_Validating( object sender,
 System.ComponentModel.CancelEventArgs e )
{
 string error = null;
 // Perform your test
 if ( textBoxName.Text.Length == 0 )
 {
  // If the test fails, set the error string
  // and cancel the validation event.
  error = "Please enter a name";
  e.Cancel = true;
 }
 // Update the state of an error provider with
 // the correct error text. Set to null for no
 // error.
 this.errorProviderAll.SetError( textBoxName, error );
}

你有幾個小工作要完成,以確保沒有不合法的輸入愉愉的混過去 了。每一個控件包含一個CausesValidation屬性,這個屬性決定這個控件是否參 與驗證。一般情況,你應該讓所有控件的這一屬性為真,除非是Cancel按鈕。如 果你忘記了,用戶還必須輸出正確的值以後才能取消對話框。第二個小任務是添 加OK句柄來強制驗證所有的控件。驗證只有在用戶訪問和離開控件時觸發。如果 用戶打開了一個窗口,然後馬上點OK,你的所有驗證代碼都不會執行。為了修正 這個,你要添加OK按鈕句柄,來訪問所有的控件,然後強制驗證它們。下面兩個 常規方法顯示了如何正確的完成任務。遞歸方法處理控件以及它所包含的控件: Tab頁面,控件組以及控件面板:

private void buttonOK_Click( object sender,
 System.EventArgs e )
{
 // Validate everyone:
 // Here, this.DialogResult will be set to
 // DialogResult.OK
 ValidateAllChildren( this );
}
private void ValidateAllChildren( Control parent )
{
 // If validation already failed, stop checking.
 if( this.DialogResult == DialogResult.None )
  return;
 // For every control
 foreach( Control c in parent.Controls )
 {
  // Give it focus
  c.Focus( );
  // Try and validate:
  if (!this.Validate( ))
  {
   // when invalid, don't let the dialog close:
    this.DialogResult = DialogResult.None;
   return;
  }
  // Validate children
  ValidateAllChildren( c );
 }
}

這些代碼可以處理大多數情況。一個特殊的快捷應 用就是DataGrid/DataSet的組合。在設計時指定ErrorProvider的DataSource以 及DataMember屬性:

ErrProvider.DataSource = myDataSet;
ErrProvider.DataMember = "Table1";

或者在運行 時,調用BindToDataAndErrors 方法來同時設置:

ErrProvider.BindToDataAndErrors( myDataSet, "Table1" );

錯誤會在設置DataRow.RowError 屬性以 及調用DataRow.SetColumnError 方法時顯示特殊的錯誤。ErrorProvider 會在 DataGrid的原始的行上的特殊單元格裡顯示紅色的警告圖標。

大概的了 解(whirlwind tour)了一下.net框架裡的控件驗證,這可能對你很有幫助,在很 多應用程序中,你都可以創建出你所須要的高效驗證。用戶的輸入不能完全信任 :用戶可能會出現錯誤,而且有時會有一些惡意的用戶試圖破壞你的應用程序。 通過.Net框架已經提供的服務,你可以減少你自己的代碼編寫工作。驗證所有用 戶的輸入,但要使用已經提供了的高效工具。

返回教程目錄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved