整理自實戰專案的高頻踩坑點與效率技巧,涵蓋基礎語法、ASP.NET WebForms/MVC 共通細節、資料庫操作、前端互動等,適合速查與 Code Review 參考。
| # | 主題 | 核心內容 | 程式碼/設定範例 |
|---|---|---|---|
| 1 | 建構函數無回傳型別 | 建構函數隱式回傳 `this`,不可寫 `void`/`int` 等。 | `public MyClass() { }` ✅ `public void MyClass() { }` ❌ |
| 2 | 字串轉日期 | 用 `DateTime.Parse`(自動格式)或 `DateTime.ParseExact`(指定格式),避免文化特性導致誤解析。 | `DateTime.ParseExact("2023-12-25", "yyyy-MM-dd", CultureInfo.InvariantCulture)` |
| 3 | `!Page.IsPostBack` 守護初始化 | 只在首次載入執行資料繫結/控制項初始化,PostBack 時跳過,保留使用者輸入/選擇。 | `if (!IsPostBack) { BindGrid(); ddlYear.SelectedValue = DateTime.Now.Year.ToString(); }` |
| 4 | GridView `HtmlEncode` 陷阱 | `BoundField.HtmlEncode="true"` (預設) → **HTML 編碼顯示**(標籤變文字)。若要**渲染 HTML**(如圖片連結),必須設 `HtmlEncode="false"`。 | ` |
| 5 | 資料繫結日期格式化差異 | `Eval("Date", "{0:yyyy-MM-dd}")` (ASP.NET 資料繫結語法) vs `DateTime.Now.ToString("yyyy-MM-dd")` (C# 標準格式字串) — 格式字串語法一致,但 `Eval` 需包在 `{0:...}` 內。 | `<%# Eval("CreateTime", "{0:yyyy/MM/dd HH:mm}") %>` |
| 6 | `NVarChar(Max)` 在 .NET 2.0 不支援 | SQL Server 2005+ 支援 `NVARCHAR(MAX)` (2GB),但 .NET 2.0 `SqlParameter` 最大僅 4000 字元。升級 .NET 4.0+ 或改用 `SqlDbType.NVarChar` + `Size = -1`。 | `param.Size = -1; // 代表 MAX` |
| 7 | Guid 空值判斷 | Guid 是實質型別,不可為 `null`。空值用 `Guid.Empty` 比較,而非 `== null`。 | `Guid id = new Guid(str); if (id == Guid.Empty) { /* 空 */ }` |
| 8 | 欄位預設值而非 NULL | 資料庫欄位盡量設 `DEFAULT` 約束(如 `GETDATE()`, `0`, `''`),C# 實體類別屬性給預設值,避免 `DBNull.Value` 轉換拋異常(特別是 `DateTime`、`Guid`)。 | `public DateTime CreateTime { get; set; } = DateTime.Now;` |
| 9 | 統計筆數用 `ExecuteScalar` | 單值查詢(COUNT、MAX、SUM)用 `cmd.ExecuteScalar()`,回傳 `object` 需轉型,比 `ExecuteReader` 輕量。 | `int count = (int)cmd.ExecuteScalar();` |
| 10 | 存儲過程 `LIKE` 參數化寫法 | 通配符 `%` 在 **SQL 字串串接** 中加入,不可放在參數值裡(會被當字面文字)。 | `WHERE Title LIKE '%' + @Keyword + '%'` ✅ `param.Value = "%keyword%";` ❌ (若參數化) |
| 11 | `List |
直接用索引器取屬性:`list[0].PropertyName`。注意檢查 `Count > 0` 避免 `ArgumentOutOfRangeException`。 | `bool resolved = faultList.Count > 0 && faultList[0].IsResolved;` |
| 12 | 關閉請求驗證 `validateRequest="false"` | 輸入含 HTML 標籤(如 `text`)會觸發「潛在危險的 Request.Form 值」。頁面指令 `<%@ Page ValidateRequest="false" %>` 或 `web.config` ` |
` |
| 13 | 渲染 HTML 內容的正確屬性 | GridView `BoundField.HtmlEncode="false"` 讓標籤生效。或手動 `HttpUtility.HtmlDecode()` / `HtmlEncode()` 控制輸出。 | `litContent.Text = HttpUtility.HtmlDecode(model.HtmlContent);` |
| 14 | 登出並跳轉父視窗 | `LoginStatus` 控制項難以滿足「登出同時跳出 Frame/導向特定頁」。改用 `LinkButton` + 程式碼: | `FormsAuthentication.SignOut();` `Response.Write("");` |
| 15 | 關閉瀏覽器視窗 | 伺服器端無法直接關閉用戶視窗,需輸出 JS: | `Response.Write("");` |
| WebForms 技巧 | ASP.NET Core / Razor Pages 寫法 |
|---|---|
| `!IsPostBack` | `OnGet` / `OnPost` 分離,天然無 PostBack 概念 |
| `ValidateRequest` | 內建反 XSS:`@Html.Raw()` 需顯式標記,預設編碼輸出 |
| `FormsAuthentication` | `CookieAuthentication` / `JWT` / `Identity` |
| `ExecuteScalar` | EF Core `context.Table.CountAsync()` / Dapper `conn.ExecuteScalarAsync()` |
| `Guid.Empty` | 相同,或用 `Guid.TryParse` |
細節決定成敗。這 15 項涵蓋**型別轉換、生命週期、資料繫結、資料庫參數化、安全性、前端互動**等核心面向。建議列印貼在工位,Code Review 時逐項對照,能消除 80% 以上的低級 Bug 與安全隱患。遷移至 ASP.NET Core 時,核心觀念(參數化、編碼、空值處理)完全通用,只需適應新 API。