在早期 ASP.NET WebForms 時代,使用 jQuery Ajax 通常需要為每個後端操作創建一個獨立的 .ashx 處理程序或 .aspx 頁面。隨著功能增長,專案中會出現幾十甚至上百個處理文件,維護成本極高:
核心思想:一個通用 HttpHandler 接收所有請求,根據參數動態調用業務類方法。
public class AjaxHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
// 核心分發邏輯
}
public bool IsReusable => false;
}
實現 IRequiresSessionState 以支持 Session 讀寫。
// 獲取調用信息:命名空間.類名.方法名
string methodFullName = context.Request["METHOD"];
string dllName = context.Request["DLL"]; // 程序集名稱
// 解析類名與方法名
int lastDot = methodFullName.LastIndexOf('.');
string className = methodFullName.Substring(0, lastDot);
string methodName = methodFullName.Substring(lastDot + 1);
// 反射創建實例
Assembly asm = Assembly.Load(dllName);
Type type = asm.GetType(className);
object instance = Activator.CreateInstance(type);
// 參數綁定(關鍵難點)
List
Convert.ChangeTypeJsonConvert.DeserializeObjectprivate void SerializeAndReturn(HttpContext context, object result)
{
if (result == null) return;
Type resultType = result.GetType();
string callback = context.Request["callback"]; // JSONP 支持
if (resultType.IsClass && resultType != typeof(string))
{
if (resultType == typeof(XmlDocument))
{
context.Response.ContentType = "text/xml";
context.Response.Write(((XmlDocument)result).OuterXml);
}
else if (resultType == typeof(DataTable))
{
string json = JsonHelper.DataTableToJson((DataTable)result);
WriteResponse(context, callback, json, "application/json");
}
else
{
string json = JsonConvert.SerializeObject(result);
WriteResponse(context, callback, json, "application/json");
}
}
else
{
WriteResponse(context, callback, $"\"{result}\"", "application/json");
}
}
[AttributeUsage(AttributeTargets.Method)]
public class AjaxMethodAttribute : Attribute { }
只有標記此特性的公共方法才可被遠程調用,防止任意代碼執行風險。
Web.config 註冊:
<httpHandlers>
<add path="Ajax.ashx" verb="*" type="MyApp.AjaxHandler, MyApp" />
</httpHandlers>
jQuery 調用示例:
$.ajax({
url: "/Ajax.ashx",
data: {
"METHOD": "MyApp.Services.UserService.GetUser",
"DLL": "MyApp.Services",
"[__DOTNET__]System.String": "user123",
"[__DOTNET__]System.Int32": "10"
},
success: function(json) { console.log(json); }
});
| 優點 | 缺點/風險 |
|---|---|
| 極大減少處理文件數量 | 反射性能開銷(可緩存 Type/MethodInfo 緩解) |
| 集中處理異常、日誌、權限、序列化 | 參數綁定邏輯複雜,需妥善處理類型轉換異常 |
| 前端調用統一入口,易於攔截器擴展 | 失去靜態類型檢查,重構時易出錯 |
| 天然支持 JSONP 跨域 | 安全風險:必須嚴格驗證 [AjaxMethod] 特性 |
在 ASP.NET Core / Web API 時代,這種模式已被以下技術取代:
但對於維護舊系統或無法升級框架的項目,此模式仍是極具價值的架構優化手段。