ASP.NET AJAX (原名 Atlas) 是微軟為 ASP.NET 2.0 提供的 AJAX 框架,包含**客戶端 JavaScript 庫** (OOP 擴充、元件模型、網路堆疊) 與**伺服器端控制項** (ScriptManager、UpdatePanel、UpdateProgress、Timer),實現無縫部分頁面更新。本文說明架構、安裝步驟、專案設定與常見問題。
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<system.web>
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add tagPrefix="ajaxToolkit" namespace="AjaxControlToolkit" assembly="AjaxControlToolkit" />
</controls>
</pages>
<httpHandlers>
<remove verb="*" path="*.asmx" />
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>
</system.web>
<system.webServer> <!-- IIS 7+ 整合模式 -->
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</handlers>
</system.webServer>
<%@ Page Language="C#" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>ASP.NET AJAX Demo</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="lblTime" runat="server" Text="初始時間" />
<br />
<asp:Button ID="btnRefresh" runat="server" Text="更新時間" OnClick="btnRefresh_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
<div class="loading">載入中...</div>
</ProgressTemplate>
</asp:UpdateProgress>
</form>
</body>
</html>
protected void btnRefresh_Click(object sender, EventArgs e) {
System.Threading.Thread.Sleep(1000); // 模擬耗時運算
lblTime.Text = DateTime.Now.ToString("HH:mm:ss.fff");
}
| 問題 | 原因 | 解決 |
|---|---|---|
| UpdatePanel 不更新 / 全頁重整 | ScriptManager 缺失、Trigger 設定錯誤、JavaScript 錯誤中斷 | 確認頁面有 ` |
| ScriptResource.axd 404 / 腳本載入失敗 | web.config httpHandlers/handlers 缺少 ScriptResourceHandler 對應 | 補齊上述 web.config 設定;IIS 7+ 需 `system.webServer/handlers` |
| PageRequestManagerParserErrorException | 部分更新回傳非預期內容 (如 `Response.Write`、HTTP 錯誤頁面、非 UTF-8 編碼) | 避免在 Async PostBack 中 `Response.Write`;錯誤處理用 `ScriptManager.AsyncPostBackError` 事件 |
| UpdatePanel 巢狀更新異常 | 外層 UpdatePanel 觸發導致內層重新渲染,事件重複綁定 | 設定 `UpdateMode="Conditional"` + 明確 `Triggers`;或重構避免巢狀 |
| 大量資料更新效能差 | ViewState 傳遞、整個 Panel 重新渲染、Client 端 DOM 操作慢 | 關閉不必要 ViewState;改用 Web Service + 客戶端模板 (jQuery/JSRender);或遷移至 ASP.NET Core + SPA |
ASP.NET AJAX 是當年將 AJAX 引入 .NET 開發主流的關鍵產品,其 `ScriptManager`/`UpdatePanel` 模式極大降低了門檻。但隨著前端生態演進,**伺服器端部分更新模式已非主流**。新專案建議採用 **Web API + 客戶端框架** 或 **Blazor**,架構更清晰、效能更優、生態更豐富。