這一章把參與者固定下來。後面的程式都只是在填這張圖的某一格。

四個角色

指令在伺服器組好,在瀏覽器執行。DOM 不送回伺服器重建。

HTML 頁面擁有真實的標籤。 的 、按鈕、你後來用指令加上的 ,都在這裡。

WebFormsJS 做三件事。第一,送出時把表單序列化:一般表單用查詢字串形式, 表單用 。第二,看回應正文是不是 Action Control;是就執行,不是就把正文當成 AJAX 結果放進頁面(預設可放進一個 ,見 )。第三,在第一次整頁輸出時,若伺服器把指令放在 ,它也會執行。

宿主是任何能讀取 並寫出正文的 .NET 程式。CodeBehind 的 Controller 是文件裡的預設宿主。Razor Pages 的 也行。

類別本身幾乎不碰 HTTP。你呼叫 、,它把對應的兩碼指令累積成一份緩衝。 在前面加上 與換行。真正寫進 HTTP 回應的是宿主。

類別不認識你的資料庫,也不認識你的路由。它只負責把「對哪個節點、做哪種動作、值是什麼」編成一行文字。驗證、存檔、權限,仍寫在 或按鈕處理常式裡。

Action Control 的形狀

每一行都是同一種句子。官方 README 把第一個等號前面拆成「兩個字元的動作碼」加上「六種定位之一」。

是 Set Text。定位 表示頁面上第一個 。等號右邊是要寫入的文字。

六種定位在第 6 章展開。這裡先記三個最常用的:

你想指到 寫法 例子
動作碼後面直接接 id deMyTagId=1
圓括號 sd(btn\_Send)=1
標籤名 角括號,索引從 0 nt<form>=h3

指令由上往下執行。若上一行把某個元素的 改掉,下一行不能再用舊的 。負索引從尾端數:de<li>-1=1 刪除最後一個 。

換行、等號、雙引號在值裡面有跳脫寫法,因為這份文字既要當 INI,有時還要塞進 HTML 屬性:

想表達 在值裡寫成
換行 \$[ln];
等號 \$[eq];
雙引號 \$[dq];
多行指令折成單行 \$[sln];

兩種回應,兩種包裝

WebFormsJS 區分「瀏覽器第一次打開這頁」和「頁面已經開著、使用者又打了一次請求」。

第一次整頁輸出時,指令可以放在頁尾的標籤裡,而不是單獨一份 INI。 屬性裡的多行指令用 \$[sln]; 接起來。類別對應的方法是 。雙引號不能直接出現在 裡。

<input name="TextBox" id="TextBox" type="text" />
<web-forms ac="bc<body>=green"></web-forms>

頁面已經在瀏覽器裡、這次是 AJAX 時,回應正文就是 INI。若你要換成一整塊新的內部 HTML,官方做法是讓第一行先 到主要容器(通常是 ),後面的行再做細修。

怎麼判斷這次是 AJAX?WebFormsJS 會加一個請求標頭:名稱 ,值 。伺服器看到它,就知道不該再回完整版面。

WebFormsJS 的分支只有這一個判斷。沒有魔法定界,就是看第一段是不是 。

CodeBehind 在這張圖的哪一層

CodeBehind 是 ASP.NET Core 上的頁面框架, 是它的 View。標記支援兩種寫法:Razor 風格的 、,以及舊式的 。NuGet 上的範例把兩者並列。WebForms Core 是它的一項能力,不是它的全部。你仍然可以只做 MVC:Controller 組 Model,View 把 Model 印出來,完全不碰 。

和本書主線有關的三個接點:

  1. 版面的 會帶 。這支檔案由框架產生。引入之後, 的輸入會自動得到 。

  2. Controller 繼承 。 是預設進入點。

  3. 要把回應收成只有指令、不要再輸出 View,教學裡使用 接著 。另一段公開範例使用 並把 設為 。兩者都是在說:這次 HTTP 正文就是那份 INI。

與 屬於 CodeBehind 的 Controller,不屬於可移植的 類別。換到 Razor Pages 時,改成 ,或在第一次繪製時用 把指令嵌進頁面。