表單是 Web 互動核心。掌握 Razor 中表單處理模式:GET 顯示表單 → POST 提交 → 伺服器驗證 → 處理商業邏輯 → 重導向防重複提交 → 顯示結果。
@{
var companyName = "";
var contactName = "";
var message = "";
if (IsPost) {
// 讀取表單資料
companyName = Request["CompanyName"]?.Trim() ?? "";
contactName = Request["ContactName"]?.Trim() ?? "";
// 伺服器端驗證
if (String.IsNullOrEmpty(companyName)) {
message = "公司名稱為必填";
} else if (String.IsNullOrEmpty(contactName)) {
message = "聯絡人名稱為必填";
} else {
// 商業邏輯處理 (儲存資料庫、發送郵件等)
message = $"感謝 {contactName} (來自 {companyName}) 的提交!";
// PRG 模式:處理完成後重導向
// Response.Redirect("~/FormSuccess");
}
}
}
<!DOCTYPE html>
<html><body>
<h1>聯絡表單</h1>
@if (!String.IsNullOrEmpty(message) && !IsPost) {
<div class="alert alert-success">@message</div>
} else if (!String.IsNullOrEmpty(message) && IsPost) {
<div class="alert @(message.StartsWith("感謝") ? "alert-success" : "alert-danger")">@message</div>
}
<form method="post">
<div class="form-group">
<label>Company Name:</label>
<input type="text" name="CompanyName" value="@companyName" class="form-control" />
</div>
<div class="form-group">
<label>Contact Name:</label>
<input type="text" name="ContactName" value="@contactName" class="form-control" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</body></html>
關鍵點:
IsPost 區分 GET/POSTRequest[key] 讀取表單值value="@variable" 保持使用者輸入 (Postback 保值)Response.Redirect 避免重新整理重複提交@{
Validation.RequireField("email", "Email 為必填");
Validation.RequireField("password", "密碼為必填");
Validation.Add("email", Validator.Email("請輸入有效 Email 格式"));
Validation.Add("password", Validator.StringLength(8, 100, "密碼長度 8-100 字元"));
Validation.Add("confirmPassword",
Validator.EqualsTo("password", "兩次密碼輸入不一致"));
if (IsPost && Validation.IsValid()) {
// 所有驗證通過,處理註冊邏輯
Response.Redirect("~/RegisterSuccess");
}
}
<form method="post">
<div class="form-group">
<label>Email</label>
<input type="email" name="email" value="@Request["email"]" class="form-control" />
@Html.ValidationMessage("email")
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" />
@Html.ValidationMessage("password")
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" name="confirmPassword" class="form-control" />
@Html.ValidationMessage("confirmPassword")
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
驗證器速查: Validator.Email(), Validator.Regex(), Validator.Range(), Validator.StringLength(), Validator.EqualsTo(), Validator.DataType()。
@{
var imagePath = "";
var images = new[] { "Photo1.jpg", "Photo2.jpg", "Photo3.jpg" };
if (IsPost) {
var choice = Request["Choice"];
if (!String.IsNullOrEmpty(choice) && images.Contains(choice)) {
imagePath = "~/images/" + choice;
}
}
}
<!DOCTYPE html>
<html><body>
<h1>動態圖片檢視器</h1>
<form method="post">
<label>選擇圖片:</label>
<select name="Choice">
@foreach (var img in images) {
var selected = (Request["Choice"] == img) ? "selected" : "";
<option value="@img" @selected>@img</option>
}
</select>
<button type="submit">顯示</button>
</form>
@if (!String.IsNullOrEmpty(imagePath)) {
<div class="image-preview">
<img src="@Href(imagePath)" alt="Preview" style="max-width:100%;" />
</div>
}
</body></html>
解析:
Request["Choice"] 取得下拉選單選中的 value (檔名)Contains() 白名單驗證,防止路徑遍歷攻擊Href() 產生正確的瀏覽器 URL 路徑@if 區塊避免首次載入 (GET) 顯示空圖片@{
var uploadMessage = "";
var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif", ".pdf" };
var maxFileSize = 10 * 1024 * 1024; // 10MB
if (IsPost) {
var file = Request.Files[0];
if (file != null && file.ContentLength > 0) {
var ext = Path.GetExtension(file.FileName).ToLower();
if (!allowedExtensions.Contains(ext)) {
uploadMessage = "不支援的檔案格式";
} else if (file.ContentLength > maxFileSize) {
uploadMessage = "檔案大小超過 10MB 限制";
} else {
var fileName = Guid.NewGuid() + ext;
var savePath = Server.MapPath("~/Uploads/" + fileName);
file.SaveAs(savePath);
uploadMessage = $"上傳成功:{fileName} ({file.ContentLength:N0} bytes)";
// 儲存資料庫記錄...
}
} else {
uploadMessage = "請選擇檔案";
}
}
}
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" accept=".jpg,.jpeg,.png,.gif,.pdf" />
<button type="submit">上傳</button>
</form>
@if (!String.IsNullOrEmpty(uploadMessage)) {
<p class="@(uploadMessage.StartsWith("上傳成功") ? "success" : "error")">@uploadMessage</p>
}
關鍵設定: enctype="multipart/form-data" 表單編碼類型、**Request.Files** 存取上傳檔案、**file.SaveAs()** 儲存、**Guid** 產生唯一檔名防衝突。
@AntiForgeryToken() + 驗證 AntiForgery.Validate()@variable 自動 HTML 編碼,Html.Raw() 僅用於信任內容