主線到第 11 章已經可以寫新頁面。這一章處理搜尋時一定會碰到的另外兩個專案。它們的安裝步驟不能和第 4 章混用。

什麼時候不該用 WebForms Core

協定適合「頁面結構大致固定,互動是改文字、改樣式、加幾列、停用按鈕」。下面這些情況,公開文件沒有把它說成目標,你也不該硬做:

  • 整個畫面每秒都換版面。指令列會變得比 HTML 還長,除錯成本高過直接回傳一段片段。

  • 團隊已經用 Blazor 或前端框架描述元件狀態。再加一套 DOM 指令,同一顆按鈕會有兩個主人。

  • 你需要的是舊 Web Forms 的 、設計工具與 相容。那是下一節的移植,不是把 重寫成一百行 。

微軟給 Web Forms 開發者的現代預設仍是 Blazor:元件、事件、以及一份把舊概念逐項對過去的電子書。Razor Pages 適合表單不多、頁面為單位的站。這些是替換技術。WebForms Core 是另一種「伺服器描述畫面變化」的技術,不是微軟遷移指南裡的一步。

WebFormsForCore:舊站遷到 .NET 10

官方站把步驟寫成一條直線。下面保留那些會讓專案失敗的約束,省略贊助與支援資訊。

  1. 先備份非 SDK 風格的舊專案。用遷移工具轉成 SDK 專案。安裝與執行分開下:

    dotnet tool install -g Project2015To2017.Migrate2019.Tool
    dotnet migrate-2019 wizard

    若工具抱怨專案類型,先拿掉它點名的那個屬性再轉。

  2. 目標框架改為 。若要和 .NET Framework 雙重編譯,可以留著 。

  3. 的輸出目錄必須是專案底下的直接子目錄。文件要求設成 ,並把 與 設為 。原因是這套移植沿用經典 ASP.NET 對輸出路徑的假設。 仍輸出到 ,而且 維持程式庫; 則是可執行檔, 為 。

  4. 引用 ,文件頁面上的版本是 1.6.8。舊的 只留給 。

  5. 在 用 包住最小主機,呼叫 。

#if NETCOREAPP
using Microsoft.AspNetCore.Builder;

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();
        app.UseWebForms();
        app.Run();
    }
}
#endif

預設只接住 Web Forms 自己的請求,例如 。其餘交給 ASP.NET Core。若站點用了友善網址與路由,改成:

app.UseWebForms(opt => opt.HandleAllRequestsWithWebForms());

工作階段要改用 ASP.NET Core 的 session,再告訴移植層使用它:

builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();

app.UseSession();
app.UseWebForms(opt => opt.UseAspNetCoreSessionProvider());

記憶體快取是單一行程。多機時換成文件所說的其他提供者,例如 Redis。

套件對照

舊組件名稱要換成移植套件,不能同時引用原來的 。

@YY@ 原來的組件 & 改引用
&
&
&
與 Microsoft 的同名套件 &
&
&
AjaxControlToolkit 與其 Sanitizer、靜態資源 & 同名前綴改成

這份移植只實作屬性,好讓網站在沒有 的 Linux 上仍能啟動。不要把它當成完整的繪圖程式庫。

需要自動產生 時,再加 ,並把 設成 。文件說明它只處理 C#,不處理 Visual Basic,Visual Studio 裡的 Web 控制項視覺設計器也不能用。Build 套件還會在建置後拿掉舊組件上不相容的設計器屬性,讓某些參考了 的第三方程式庫能載入型別。那些程式庫仍是對著 .NET Framework 編譯的,載入成功不等於行為正確。

同一套 Build 提供類似 的 MSBuild 工作 ,並有全域工具 。

組件衝突

移植組件會取代 、,以及 。文件要求在 裡加一個在參考組件解析之前執行的目標,把這三個檔名從 移除,避免 NuGet 又把官方套件帶進來。條件用檔名與路徑比對。這段 XML 以官方站的範本為準,版本一變,正則也要跟著對。

WebFormsForCore 跑起來之後,頁面仍是舊的控制項樹與 PostBack。不要在同一個按鈕上再掛 Elanat 的 。兩套回傳會搶同一張表單。

WebFormsCore 框架

這一段只複述 公開 README 裡已經寫出的啟動方式。它是 ASP.NET Core 10 以上的框架,受 Web Forms 啟發,不是 的二元相容層,也沒有 協定。

手動建立時,專案 SDK 使用 。 的形狀是:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWebFormsCore();
var app = builder.Build();
app.UseWebFormsCore();
app.MapPages();
app.Run();

會從組件裡登記頁面。頁面檔用 ,頁首帶 、 與 。README 寫明:沒有 的頁面不會被 公開,也可以改用 或 手動對應。

README 另外點名兩項和經典模型相關的能力:用 標在欄位或屬性上,由原始碼產生器寫入狀態;一頁可以有多個表單,各自帶自己的 view state;範圍表單在回傳時只處理該表單內的控制項。這些都說明它走的是「頁面與控制項」模型。

三條路的第一個檔案就能分辨。看到 與 ,你在主線。看到 與 ,你在移植舊站。看到 與 ,你在 WebFormsCore。