Effective C# 使用.NET驗證

來源:互聯網
上載者:User

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

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

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

表5.1 常用的Regex

構造 含意
[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.

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

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

例如,這有一個Regex,用於驗證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架構已經提供的服務,你可以減少你自己的代碼編寫工作。驗證所有使用者的輸入,但要使用已經提供了的高效工具。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.