利用 ASP.NET AJAX 機制,透過 ScriptManager 註冊 WCF 服務 (或 ASMX WebService),自動產生 JavaScript Proxy 類別,前端 JS 即可像呼叫本地函式般非同步呼叫伺服器端 C# 方法。
Visual Studio → 新增項目 → AJAX-Enabled WCF Service (命名為 AuthService.svc)。
自動產生:
AuthService.svc:服務進入點App_Code/AuthService.cs:實作類別[ServiceContract(Namespace = "MyApp.Services")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AuthService
{
[OperationContract]
public bool ValidateUser(string username, string password)
{
// 實際專案請查詢資料庫、驗證雜湊密碼
return username == "admin" && password == "admin123";
}
[OperationContract]
public UserInfo GetUserProfile(string username)
{
return new UserInfo { Username = username, Role = "Admin", LastLogin = DateTime.Now };
}
}
[DataContract]
public class UserInfo
{
[DataMember] public string Username { get; set; }
[DataMember] public string Role { get; set; }
[DataMember] public DateTime LastLogin { get; set; }
}
<%@ Page Language="C#" %>
<html><head>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/AuthService.svc" />
</Services>
</asp:ScriptManager>
</head><body>
<form id="form1" runat="server">
<div>
帳號:<input type="text" id="txtUser" />
密碼:<input type="password" id="txtPwd" />
<input type="button" value="驗證" onclick="doValidate()" />
<br /><br />
<div id="result" style="color:blue"></div>
</div>
</form>
</body></html>
<script type="text/javascript">
function doValidate() {
var user = $get("txtUser").value;
var pwd = $get("txtPwd").value;
// 呼叫 Proxy 方法:命名空間.類別.方法(參數, 成功回調, 失敗回調, 使用者內容)
MyApp.Services.AuthService.ValidateUser(user, pwd, onValidateSuccess, onValidateFailed);
}
function onValidateSuccess(result) {
var div = $get("result");
if (result) {
div.innerHTML = "✅ 驗證通過,歡迎回來!";
div.style.color = "green";
// 可進一步導向、設定 Cookie 等
} else {
div.innerHTML = "❌ 帳號或密碼錯誤";
div.style.color = "red";
}
}
function onValidateFailed(error) {
$get("result").innerHTML = "⚠️ 呼叫失敗:" + error.get_message();
// error.get_stackTrace() 可取得堆疊追蹤
}
// 進階:呼叫回傳複雜型別
function getProfile() {
var user = $get("txtUser").value;
MyApp.Services.AuthService.GetUserProfile(user, onProfileSuccess, onValidateFailed);
}
function onProfileSuccess(userInfo) {
// userInfo 為 JSON 物件,對應 C# UserInfo DataContract
alert("角色:" + userInfo.Role + "\n上次登入:" + userInfo.LastLogin);
}
</script>
所有 Proxy 方法呼叫皆為非同步,不可直接取得回傳值:
// ❌ 錯誤寫法
var result = MyApp.Services.AuthService.ValidateUser(u, p); // 永遠是 undefined
// ✅ 正確寫法:指定成功/失敗回調
MyApp.Services.AuthService.ValidateUser(u, p, successCallback, failCallback);
[ServiceContract(Namespace = "MyApp.Services")]MyApp.Services.AuthServicehttps://tempuri.org/,JS 中需用 TempUriOrg.AuthService。標記 [DataContract] 與 [DataMember] 的類別會自動轉為 JSON 物件,日期型別轉為 ISO 8601 字串 (如 "2024-01-15T14:30:00"),JS 端可用 new Date(str) 解析。
function onFailed(error) {
// 記錄至伺服器日誌
console.error("AJAX Error:", error.get_message(), error.get_stackTrace());
// 友善提示
if (error.get_statusCode() === 401) showLoginDialog();
else if (error.get_timedOut()) showRetryButton();
else showGenericError();
}
若維護舊專案,同樣適用:
[WebService(Namespace = "MyApp.Services")]
[ScriptService] // 關鍵:啟用 AJAX 呼叫
public class AuthService : WebService
{
[WebMethod]
public bool ValidateUser(string username, string password) { ... }
}
前端註冊方式相同:<asp:ServiceReference Path="~/AuthService.asmx" />。
__RequestVerificationToken,確保 ScriptManager 設定 EnablePageMethods="true"。新專案建議採用 ASP.NET Core Web API + fetch/axios 或 Blazor WebAssembly,架構更清晰、工具鏈更現代、支援 TypeScript 強型別。