ASP.NET WebForms 內建驗證控制項提供聲明式的客戶端/伺服器端雙重驗證機制。本文深度解析兩大核心控制項:RegularExpressionValidator (正則表達式驗證) 與 CustomValidator (自定義邏輯驗證),並附贈常用正則表達式速查表。
<asp:RegularExpressionValidator
ID="revEmail"
runat="server"
ControlToValidate="txtEmail"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
ErrorMessage="郵件格式不正確"
Display="Dynamic"
CssClass="text-danger"
SetFocusOnError="true">
</asp:RegularExpressionValidator>
| 屬性 | 說明 |
|---|---|
| ControlToValidate | 要驗證的輸入控制項 ID |
| ValidationExpression | 正則表達式模式 (不含 /.../ 定界符) |
| ErrorMessage | 驗證失敗顯示的錯誤訊息 |
| Display | Static(佔位)、Dynamic(不佔位)、None(隱藏) |
| SetFocusOnError | 驗證失敗時自動聚焦至該控制項 |
| EnableClientScript | 是否啟用客戶端腳本驗證 (預設 true) |
| 驗證項目 | 正則表達式 | 說明 |
|---|---|---|
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ | 標準郵件格式 | |
| URL | ^(https?|ftp)://[^\s/$.?#].[^\s]*$ | 含協定的網址 |
| 手機號 (台灣) | ^09\d{8}$ | 09 開頭 10 碼 |
| 手機號 (大陸) | ^1[3-9]\d{9}$ | 13-19 開頭 11 碼 |
| 身分證字號 (台灣) | ^[A-Z][12]\d{8}$ | 英文+數字 10 碼 |
| 統一編號 (台灣) | ^\d{8}$ | 8 位數字 |
| 郵遞區號 (台灣 3+3) | ^\d{3}(\d{3})?$ | 3 或 6 碼 |
| 中文字符 | ^[\u4e00-\u9fa5]+$ | 純中文 |
| 英文數字底線 | ^\w+$ | [a-zA-Z0-9_] |
| 密碼強度 (8-16 位、含大小寫數字特殊) | ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,16}$ | 正向前瞻斷言 |
| IPv4 | ^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$ | 0.0.0.0 ~ 255.255.255.255 |
| 日期 (yyyy-MM-dd) | ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ | 格式驗證 (不檢查日期有效性) |
| 符號 | 含義 | 範例 |
|---|---|---|
. | 任意單一字元 (換行除外) | a.c 匹配 abc, axc |
\d | 數字 [0-9] | \d{3} 匹配 123 |
\D | 非數字 | |
\w | 單字字元 [a-zA-Z0-9_] | |
\W | 非單字字元 | |
\s | 空白字元 (空格、Tab、換行) | |
\S | 非空白字元 | |
^ | 字串開頭 | ^A 以 A 開頭 |
$ | 字串結尾 | Z$ 以 Z 結尾 |
* | 0 次或多次 {0,} | ab*c ac, abc, abbc |
+ | 1 次或多次 {1,} | ab+c abc, abbc |
? | 0 次或 1 次 {0,1} | ab?c ac, abc |
{n} | 恰好 n 次 | \d{4} 4 位數字 |
{n,} | 至少 n 次 | |
{n,m} | n 到 m 次 | |
| | 或 | cat|dog |
() | 分組/捕獲 | (ab)+ ababab |
[] | 字元集合 | [aeiou] 母音 |
[^] | 排除字元集合 | [^0-9] 非數字 |
<asp:CustomValidator
ID="cvUserName"
runat="server"
ControlToValidate="txtUserName"
OnServerValidate="cvUserName_ServerValidate"
ErrorMessage="此帳號已被註冊"
Display="Dynamic"
CssClass="text-danger">
</asp:CustomValidator>
protected void cvUserName_ServerValidate(object source, ServerValidateEventArgs args)
{
string inputValue = args.Value; // 使用者輸入的值
// 業務邏輯:檢查資料庫是否存在
using (var conn = new SqlConnection(ConnString))
using (var cmd = new SqlCommand("SELECT COUNT(*) FROM Users WHERE UserName = @Name", conn))
{
cmd.Parameters.AddWithValue("@Name", inputValue);
conn.Open();
int count = (int)cmd.ExecuteScalar();
args.IsValid = (count == 0); // true = 驗證通過,false = 失敗
}
}
<asp:CustomValidator
ID="cvPassword"
runat="server"
ControlToValidate="txtPassword"
ClientValidationFunction="validatePasswordStrength"
OnServerValidate="cvPassword_ServerValidate"
ErrorMessage="密碼強度不足">
</asp:CustomValidator>
<script>
function validatePasswordStrength(sender, args) {
var value = args.Value;
// 客戶端邏輯:至少 8 碼、含大小寫、數字
var regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
args.IsValid = regex.test(value);
}
</script>
驗證多個欄位關聯邏輯 (如「確認密碼」):
<asp:CustomValidator
ID="cvConfirmPassword"
runat="server"
ClientValidationFunction="validatePasswordMatch"
OnServerValidate="cvConfirmPassword_ServerValidate"
ErrorMessage="兩次密碼不一致"
Display="Dynamic">
</asp:CustomValidator>
<script>
function validatePasswordMatch(sender, args) {
var pwd = document.getElementById('<%= txtPassword.ClientID %>').value;
var confirm = document.getElementById('<%= txtConfirmPassword.ClientID %>').value;
args.IsValid = (pwd === confirm && pwd.length > 0);
}
</script>
<!-- 登入區塊 -->
<asp:TextBox ID="txtLoginName" runat="server" ValidationGroup="LoginGroup" />
<asp:RequiredFieldValidator ControlToValidate="txtLoginName" ValidationGroup="LoginGroup" ... />
<asp:Button ID="btnLogin" runat="server" Text="登入" ValidationGroup="LoginGroup" />
<!-- 註冊區塊 -->
<asp:TextBox ID="txtRegName" runat="server" ValidationGroup="RegGroup" />
<asp:RequiredFieldValidator ControlToValidate="txtRegName" ValidationGroup="RegGroup" ... />
<asp:Button ID="btnRegister" runat="server" Text="註冊" ValidationGroup="RegGroup" />
protected void btnSubmit_Click(object sender, EventArgs e)
{
// 1. 執行特定群組驗證
Page.Validate("RegGroup");
// 2. 或執行所有驗證
Page.Validate();
// 3. 檢查整體是否通過
if (Page.IsValid)
{
// 全部通過,執行業務邏輯
SaveData();
}
else
{
// 有失敗,可遍歷 Validators 收集錯誤
foreach (BaseValidator validator in Page.Validators)
{
if (!validator.IsValid)
{
// 記錄或處理 validator.ErrorMessage
}
}
}
}
public class RegisterViewModel
{
[Required(ErrorMessage = "請輸入帳號")]
[StringLength(20, MinimumLength = 4, ErrorMessage = "帳號長度 4-20 碼")]
[Remote("CheckUserName", "Account", ErrorMessage = "帳號已存在")] // AJAX 遠端驗證
public string UserName { get; set; }
[Required(ErrorMessage = "請輸入 Email")]
[EmailAddress(ErrorMessage = "Email 格式錯誤")]
public string Email { get; set; }
[Required(ErrorMessage = "請輸入密碼")]
[DataType(DataType.Password)]
[StringLength(16, MinimumLength = 8, ErrorMessage = "密碼長度 8-16 碼")]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$", ErrorMessage = "需含大小寫字母與數字")]
public string Password { get; set; }
[Compare("Password", ErrorMessage = "兩次密碼不一致")]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
}
ASP.NET 驗證控制項提供了聲明式、雙端同步的驗證機制。RegularExpressionValidator 適合格式驗證,配合豐富的正則庫可覆蓋 90% 輸入檢查需求;CustomValidator 處理複雜業務規則、跨欄位驗證、資料庫查重。掌握正則元字元、驗證群組、手動觸發、ValidationSummary 等進階用法,即可構建健壯的表單驗證體系。新專案建議遷移至 MVC/Core 的 Data Annotations + FluentValidation 架構。