導(dǎo)言
在強(qiáng)大的.net面前,我有很多的想法,我希望asp.net的web控件內(nèi)建有驗(yàn)證功能,而不需要在頁(yè)面中插入太多的驗(yàn)證控件以致代碼混亂!現(xiàn)在我們將可以利用.net來(lái)創(chuàng)建一個(gè)只允許輸入整型數(shù)字的的textbox控件或只允許輸入貨幣型數(shù)據(jù)的textbox控件,等等。當(dāng)然了,你還可以特別指定textbox控件可否為空或者是否在一個(gè)范圍內(nèi),等等,另外,當(dāng)我們輸入的數(shù)據(jù)符合要求時(shí),還可以返回一個(gè)值,以方便我們覺(jué)得是否要干預(yù),甚至我們可以讓它運(yùn)行的時(shí)候根據(jù)輸入數(shù)據(jù)是否符合要求呈現(xiàn)不同的顏色
經(jīng)過(guò)一番努力,我終于實(shí)現(xiàn)以上的想法
實(shí)現(xiàn)ivalidator接口
我在鉆研sdk文檔時(shí)發(fā)現(xiàn),只要實(shí)現(xiàn)了ivalidator接口,任何的控件都可以具有驗(yàn)證功能,以下是一個(gè)繼承textbox控件的簡(jiǎn)單的例子:
using system;
using system.web.ui.webcontrols;
using system.web.ui;
namespace myvalidatingcontrols {
public class textbox : system.web.ui.webcontrols.textbox, ivalidator {
private bool _valid = true;
private string _errormessage = "";
public bool isvalid {
get { return _valid; }
set { _valid = value; }
}
public string errormessage {
get { return _errormessage; }
set { _errormessage = value; }
}
public void validate() {
}
}
}
當(dāng)然了,這段程序什么都不做,但是它完全實(shí)現(xiàn)了基本的ivalidator接口的架構(gòu)(至少它是可以成功編譯的),我使用private關(guān)鍵字創(chuàng)建兩個(gè)字段(field)用來(lái)保存驗(yàn)證狀態(tài)和錯(cuò)誤信息,為了確保驗(yàn)證控件能被執(zhí)行,我們必須把我們的驗(yàn)證控件添加到頁(yè)面中的驗(yàn)證控件集合中來(lái)。
我在閱讀sdk文檔的時(shí)候發(fā)現(xiàn),驗(yàn)證控件是在初始化期間加載他們本身的,ivalidators接口主要用來(lái)注冊(cè)他們自己,所以我們需要使用覆蓋的方法重新實(shí)現(xiàn)oninit和onunload事件,以便我們能從頁(yè)面中的驗(yàn)證控件集合中添加或者刪除它們
protected override void oninit(eventargs e) {
base.oninit(e);
page.validators.add(this);
}
protected override void onunload(eventargs e) {
if (page != null) {
page.validators.remove(this);
}
base.onunload(e);
}
完成設(shè)置
在我們實(shí)現(xiàn)我們的驗(yàn)證功能之前,為了使事件更簡(jiǎn)潔,我設(shè)置了一些幫助項(xiàng)目,因?yàn)槲也幌雴为?dú)分別單獨(dú)提供驗(yàn)證控件的錯(cuò)誤信息,而是希望把他們嵌入到控件中來(lái),以實(shí)現(xiàn)我們所期望格式的數(shù)據(jù)錄入,因此,我需要做一些事情,使它可以適當(dāng)?shù)某霈F(xiàn)錯(cuò)誤提示。
我將添加一個(gè)叫做friendlyname屬性,它將在所有的錯(cuò)誤提示信息中出現(xiàn)以提示用戶合法的數(shù)據(jù)類型,所以,如果我們調(diào)用的控件id是retailprice,我們將使該控件的riendlyname為retail price
private string _friendlyname = "";
public string friendlyname {
get { return _friendlyname; }
set { _friendlyname = value; }
}
最后,我們重寫(xiě)isvalid事件,使它可以在驗(yàn)證不通過(guò)時(shí)可以改變控件的背景顏色
public bool isvalid {
get { return _valid; }
set {
_valid = value;
if (!_valid) {
this.backcolor = color.lightcoral;
}
else {
this.backcolor = color.white;
}
}
}
不允許出現(xiàn)空格
首先我們需要確定,提供一個(gè)可選項(xiàng)以決定是否允許為空值,我們?cè)谶@里需要?jiǎng)?chuàng)建一個(gè)屬性以判斷是否可以為空
private bool _blankallowed = true;
public bool allowblank {
get { return _blankallowed; }
set { _blankallowed = value; }
}
最后,我們可以重寫(xiě)驗(yàn)證函數(shù)
public virtual void validate() {
this.isvalid = true;
if (!this.allowblank) {
bool isblank = (this.text.trim() == "");
if (isblank) {
this.errormessage =
string.format("'{0}' cannot be blank.",
this.friendlyname);
this.isvalid = false;
}
}
}
拓展我們的創(chuàng)意
現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè)內(nèi)建基本驗(yàn)證功能的textbox控件,現(xiàn)在我們可以延展我們的想法,創(chuàng)建更多的有趣的具有特定驗(yàn)證功能的textbox控件
下面以創(chuàng)建一個(gè)只允許輸入整型數(shù)據(jù)的textbox控件(integertextbox),并且使該控件具有只允許輸入的數(shù)據(jù)必須在一定的范圍內(nèi),但我們?nèi)匀恍枰紤]是否允許空值,所以,象上面一樣,需要添加一個(gè)屬性
在上面我們創(chuàng)建的基本的textbox控件的基礎(chǔ)上,我們僅僅需要繼承該控件,然后覆蓋validate函數(shù)和添加一些新的屬性
private int _minvalue = int32.minvalue;
private int _maxvalue = int32.maxvalue;
public int minvalue {
get { return _minvalue; }
set {
_minvalue = value;
if (_minvalue > _maxvalue) {
int swap = _minvalue;
_minvalue = _maxvalue;
_maxvalue = swap;
}
}
}
public int maxvalue {
get { return _maxvalue; }
set {
_maxvalue = value;
if (_minvalue > _maxvalue) {
int swap = _minvalue;
_minvalue = _maxvalue;
_maxvalue = swap;
}
}
}
然后,我們擴(kuò)充該validate函數(shù),并把編譯它為本地代碼
public override void validate() {
this.isvalid = true;
bool isblank = (this.text.trim() == "");
if (isblank) {
if (!allowblank) {
this.errormessage = string.format("'{0}' " +
"cannot be blank.", this.friendlyname);
this.isvalid = false;
}
} else {
try {
_value = int32.parse(this.text);
if (_value < this.minvalue) {
this.errormessage = string.format("'{0}' cannot " +
"be less than {1}",
this.friendlyname, this.minvalue);
this.isvalid = false;
}
if (_value > this.maxvalue) {
this.errormessage = string.format("'{0}' " +
"cannot be more than {1}",
this.friendlyname, this.minvalue);
this.isvalid = false;
}
} catch {
this.errormessage = string.format("'{0}' " +
"is not a valid integer.", this.friendlyname);
this.isvalid = false;
}
}
}
public int value {
get { return _value; }
set {
_value = value;
this.text = _value.tostring();
}
}
結(jié)論
要寫(xiě)就那么多了,現(xiàn)在我們還可以在這個(gè)類的基礎(chǔ)上創(chuàng)建諸如要求只能輸入符合一定時(shí)間格式和貨幣格式,下面我們舉一個(gè)例子以說(shuō)明如何使用我們創(chuàng)建的控件
在此以前我們要實(shí)現(xiàn)同樣的功能需要寫(xiě)以下的代碼:
<asp:textbox id="number" runat="server"/>
<asp:requiredfieldvalidator id="requiredfieldvalidator2"
controltovalidate="number"
text="'number' cannot be blank." runat="server"/>
<asp:rangevalidator id="range1" controltovalidate="number"
minimumvalue="0" maximumvalue="100"
type="integer" text="the value must be from 0 to 100!"
runat="server"/>
而現(xiàn)在,我們僅僅需一句:
mycontrols:integertext id="number"
friendlyname="number" minvalue="0" maxvalue="100"
allowblank="false" runat="server">
最后,需要說(shuō)明的是,我創(chuàng)建的這個(gè)類相對(duì)與現(xiàn)有的驗(yàn)證來(lái)說(shuō)并不那么完美,一個(gè)明顯需要改進(jìn)地方是,我們需要在該類中添加客戶端腳本,以使驗(yàn)證行為可以不只在服務(wù)器端觸發(fā),也可以在客戶端觸發(fā)
我希望每一個(gè)人都能理解它的運(yùn)行原理,以便你有更好的創(chuàng)意的時(shí)候可以修正它,也許有一天我可能會(huì)使用你創(chuàng)建的具有完美功能的類集。
新聞熱點(diǎn)
疑難解答
圖片精選