核心差異一覽
| 特性 |
DataBinder.Eval |
Eval (ASP.NET 2.0+) |
| 語法 |
DataBinder.Eval(Container.DataItem, "Field") |
Eval("Field") |
| 容器解析 |
需明確指定 Container.DataItem |
自動從最近的資料繫結容器取得 |
| 適用範圍 |
任何位置(含 Page 層級) |
僅限資料繫結控制項模板內 |
| 格式化參數 |
支援 {0:format} |
支援 {0:format} |
| 效能 |
反射呼叫,稍慢 |
內部同樣用反射,語法糖無額外成本 |
Eval vs Bind
- Eval:單向唯讀繫結,適用
ItemTemplate、AlternatingItemTemplate 顯示資料。
- Bind:雙向繫結,用於
EditItemTemplate、InsertItemTemplate,GridView/DetailsView 更新/插入時自動提取值。
常用格式化範例
<!-- 直接繫結 -->
<%# Eval("ProductName") %>
<!-- 自動編號 -->
<%# Container.DataItemIndex + 1 %>
<!-- 日期格式化 -->
<%# Eval("CreateDate", "{0:yyyy-MM-dd HH:mm}") %>
<%# Bind("CreateDate", "{0:yyyy-MM-dd}") %>
<!-- 數字格式化:兩位小數、千分位 -->
<%# Eval("Price", "{0:N2}") %>
<%# Eval("Amount", "{0:#,##0.00}") %>
<!-- 布林轉中文 -->
<%# (bool)Eval("IsActive") ? "啟用" : "停用" %>
<!-- 字串截取 -->
<%# Eval("Description").ToString().Substring(0, Math.Min(20, Eval("Description").ToString().Length)) + "..." %>
<!-- 條件顯示 -->
<%# Eval("Status").ToString() == "1" ? "審核通過" : "待審核" %>
進階技巧:在模板中呼叫自訂方法
<%# FormatStatus(Eval("Status")) %>
// 後端
protected string FormatStatus(object status)
{
switch (status?.ToString())
{
case "1": return "<span class='badge success'>通過</span>";
case "0": return "<span class='badge warning'>待審</span>";
default: return "<span class='badge danger'>駁回</span>";
}
}
常見錯誤與避坑指南
- Page_Load 使用 Eval:編譯錯誤「The name 'Container' does not exist」。→ 改用
DataBinder.Eval 或移至模板內。
- 格式化字串寫錯:
{0:yyyy-mm-dd} (mm=分鐘) → 應為 {0:yyyy-MM-dd} (MM=月份)。
- Null 參考例外:資料欄位為 DBNull → 使用
Eval("Field") ?? "" 或在方法中處理 null。
- Bind 用於唯讀模板:會導致更新時找不到控制項 → 唯讀務必用 Eval。
最佳實務建議
- 新專案優先使用
Eval/Bind 簡潔語法。
- 複雜格式化邏輯抽離至後端 protected 方法,模板保持乾淨。
- 需在非模板位置(如 CodeBehind 動態建立控制項)繫結時,使用
DataBinder.Eval。
- 資料來源為
List<T> 或匿名類型時,Eval("PropertyName") 同樣適用。