首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

解決 DynamicControl/DynamicField PostBack 例外:自訂 DdControl/DdField 避開 MetaTable 為 Null 問題

     編輯:關於.NET

錯誤現象

使用 ASP.NET Dynamic Data 的 DynamicField / DynamicControl 時,PostBack 會拋出:

The DynamicControl/DynamicField needs to exist inside a data control that is bound to a data source that supports Dynamic Data.

中文:綁定到支援動態資料之資料來源的資料控制項內,必須存在 DynamicControl/DynamicField。

根因分析

PostBack 事件流程與初始載入不同。資料控制項 (DetailsView, GridView, ListView 等) 在狀態載入階段會初始化所有 Fields/Columns,但此時資料來源尚未繫結,導致找不到 MetaTable,進而拋出例外。若在 InitComplete 前完成資料繫結可避免,但許多專案習慣在 Load 階段繫結,改動成本高。

解決方案:繼承並覆寫初始化邏輯

自訂 DdField、DdControl,在初始化前檢查 FindMetaTable() 是否為 null,若無則略過初始化,避免拋出例外。

完整原始碼

namespace Common
{
    /// 
    /// 修正 DynamicField PostBack 找不到 MetaTable 的例外
    /// 
    public class DdField : DynamicField
    {
        public override void InitializeCell(
            DataControlFieldCell cell,
            DataControlCellType cellType,
            DataControlRowState rowState,
            int rowIndex)
        {
            // HACK: 若找不到 MetaTable,直接返回,不進行後續初始化
            if (base.Control.FindMetaTable() == null) return;
            base.InitializeCell(cell, cellType, rowState, rowIndex);
        }
    }
}

namespace Common
{
    /// 
    /// 修正 DynamicControl PostBack 找不到 MetaTable 的例外
    /// 
    public class DdControl : DynamicControl
    {
        protected override void OnInit(EventArgs e)
        {
            // HACK: 僅在找到 MetaTable 時才呼叫基底 OnInit
            if (this.FindMetaTable() != null) base.OnInit(e);
        }
    }
}

Web.config 註冊標籤前綴

<configuration>
  <system.web>
    <pages>
      <controls>
        <!-- 假設編譯後為 Common.dll -->
        <add tagPrefix="asp" namespace="Common" assembly="Common" />
      </controls>
    </pages>
  </system.web>
</configuration>

頁面使用範例

<DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False">
  <Fields>
    <asp:DdField DataField="Name" />
    <asp:DdField DataField="Email" />
  </Fields>
</DetailsView>

原理說明

類別覆寫方法攔截時機
DdFieldInitializeCell資料控制項建立儲存格時,檢查 MetaTable 是否存在
DdControlOnInit控制項 Init 階段,檢查 MetaTable 是否存在

若 FindMetaTable() == null 表示資料來源尚未繫結或不支援 Dynamic Data,直接跳過初始化,避免拋出例外。後續資料繫結完成後,控制項會重新經歷生命週期並正常運作。

適用性與限制

  • ✅ 解決 PostBack 時的例外,不需調整既有資料繫結時機。
  • ✅ 相容現有 Eval/Bind 語法,開發體驗無差異。
  • ⚠️ 若資料來源永遠不支援 Dynamic Data,控制項將永不渲染,需確認資料來源型別正確。
  • ⚠️ 僅針對 Dynamic Data 框架內建控制項,第三方控制項需類似處理。

作者備註

作者近期大量使用 DynamicFieldTemplates 開發應用,對此類問題深有體會。若發現 Bug 請來信回報,持續維護中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved