由於jquery的出現,編寫js代碼已經變得異常的平民化,同時現在的web也已經是ajax滿天飛,哪天你自己寫一個web不含ajax的拿不出手
當然,在.net的控件模式開發中一種去控件化開發已經變的變得更加通用:jquery+ajax+ashx 這種方式更加適用於一些小應用的開發,輕量、簡單、自由
由於那時候太年輕,剛剛開始這種模式開發的時候 是一個ajax請求一個ashx頁面,這樣的結果可想而知,一個小的權限系統光光ashx文件就幾十個了,而且文件名還大同小異,悲劇。
后來做了一會兒變聰明了,把相同類別的請求都放到一個ashx文件中,每個請求傳一個請求標志 通過switch來調用相應的請求方法,當然,這樣要比原來好多了,至少沒那么多ashx文件了,但是 每新建一個文件都要去添加switch方法,蛋疼啊 有木有,更加可恥的是 每次增刪改一個請求都要去修改那個可惡的switch語句,煩啊
后來知道了反射,知道可以用反射來動態調用方法,腦子一轉,哇 好主意,查了相關資料,沒幾分鍾就把這個框架寫了出來,然后百度一搜,次奧,關於這種的都有那么多文章了,本來都不想再寫這篇文章,重復造輪子啊 要被罵的有木有,不過想想代碼都寫了,而且還是自己寫的,寫篇文章紀念一下,而且這個東西感覺比網上的更加方便,實用,嘿嘿。
下面就是這個handler主心骨雞類的詳解了
首先在這個雞類中定義幾個默認的參數
/// <summary>
/// 指定過來的http請求類型 主要指定action方法名稱的接收方式 get 或者 post
/// </summary>
protected NameValueCollection _httpReuqest = HttpContext.Current.Request.Form;
/// <summary>
/// 指定返回頭
/// </summary>
protected string _contentType = "text/plain";
/// <summary>
/// 指定接收action方法的參數名稱
/// </summary>
protected string _actionName = "action";
主要是定義默認的請求方式 GET或者POST 當然默認是POST,相對安全點嘛,並且個人用的也多,當然這個請求方式在子類中可以把它改掉呢
還有就是請求的返回頭,方法名稱的參數 代碼的注釋里面都寫得很清楚呢
下面就是動態調用方法的核心代碼啦(再這里給個反射連接的相關知識,不知道的點我哦)
//根據指定的請求類型獲取方法名
string action = this._httpReuqest[this._actionName];
if (!string.IsNullOrEmpty(action))
{
//獲取方法的實例 非靜態 需要Public訪問權限 忽略大小寫
MethodInfo methodInfo = this.GetType().GetMethod(action, BindingFlags.Instance|BindingFlags.Public|BindingFlags.IgnoreCase);
if (methodInfo != null)
{
//調用方法
methodInfo.Invoke(this, null);
}
else
{
throw new ApplicationException(string.Format("沒有找到方法{0}", action));
}
}
else
{
throw new ArgumentNullException("沒有找到調用方法參數或者方法名為空");
}
核心代碼夠簡單把 其實最核心的就是獲取方法實例,當然該方法,兩句啦 方便吧
我們看看這個獲取方法實例的代碼
主要是獲取類中的非靜態,公開訪問,忽略名稱大小寫的方法,當然你如果不放心 其他的方法也被ajax跨域調用了,你可以給該方法的訪問權限設為private或者protected 如果你還是不放心的話 可以喝其他的一樣 自定義一個Attribute特征加在方法頭上,不過個人在這里感覺沒啥必要了
核心的都給你們看了 那來看下雞類的全部代碼吧
/// <summary>
/// Handler請求的基類 用此類動態調用請求的方法
/// </summary>
public class HandlerBase : IHttpHandler
{
/// <summary>
/// 指定過來的http請求類型 主要指定action方法名稱的接收方式 get 或者 post
/// </summary>
protected NameValueCollection _httpReuqest = HttpContext.Current.Request.Form;
/// <summary>
/// 指定返回頭
/// </summary>
protected string _contentType = "text/plain";
/// <summary>
/// 指定接收action方法的參數名稱
/// </summary>
protected string _actionName = "action";
//獲取當前的http context
protected HttpContext Context
{
get {
return HttpContext.Current;
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = this._contentType;
try
{
//動態調用方法 當然 你還可以在這里加上是否為同域名請求的判斷
this.DynamicMethod();
}
catch (AmbiguousMatchException amEx)
{
this.PrintErrorJson(string.Format("根據該參數{0}找到了多個方法",amEx.Message));
}
catch (ArgumentException argEx)
{
this.PrintErrorJson("參數異常" + argEx.Message);
}
catch (ApplicationException apEx)
{
this.PrintErrorJson("程序異常" + apEx.Message);
}
}
#region 動態調用方法
/// <summary>
/// 動態調用方法
/// </summary>
private void DynamicMethod()
{
//根據指定的請求類型獲取方法名
string action = this._httpReuqest[this._actionName];
if (!string.IsNullOrEmpty(action))
{
//獲取方法的實例 非靜態 需要Public訪問權限 忽略大小寫
MethodInfo methodInfo = this.GetType().GetMethod(action, BindingFlags.Instance|BindingFlags.Public|BindingFlags.IgnoreCase);
if (methodInfo != null)
{
//調用方法
methodInfo.Invoke(this, null);
}
else
{
throw new ApplicationException(string.Format("沒有找到方法{0}", action));
}
}
else
{
throw new ArgumentNullException("沒有找到調用方法參數或者方法名為空");
}
}
#endregion
#region 打印Json的相關處理
/// <summary>
/// 打印遇到異常的json
/// </summary>
/// <param name="msg"></param>
protected void PrintErrorJson(string msg)
{
this.PrintJson("error", msg);
}
/// <summary>
/// 打印成功處理的json
/// </summary>
/// <param name="msg"></param>
protected void PrintSuccessJson(string msg)
{
this.PrintJson("success", msg);
}
/// <summary>
/// 打印json
/// </summary>
/// <param name="state"></param>
/// <param name="msg"></param>
protected void PrintJson(string state, string msg)
{
this.Context.Response.Write("{\"state\":\""+state+"\",\"msg\":\"" + msg + "\"}");
}
#endregion
public bool IsReusable
{
get
{
return false;
}
}
}
夠簡單把,然后寫幾個測試ashx頁面繼承該基類就可以啦
/// <summary>
/// Get一般處理程序的測試
/// </summary>
public class gethandler : HandlerBase
{
public gethandler()
{
//修改請求為get 方式
base._httpReuqest = base.Context.Request.QueryString;
}
/// <summary>
/// 加法操作
/// </summary>
public void Add()
{
int a = Convert.ToInt32(_httpReuqest["a"]);
int b = Convert.ToInt32(_httpReuqest["b"]);
PrintSuccessJson((a + b).ToString());
}
/// <summary>
/// 減法操作
/// </summary>
private void Minus()
{
int a = Convert.ToInt32(_httpReuqest["a"]);
int b = Convert.ToInt32(_httpReuqest["b"]);
PrintSuccessJson((a - b).ToString());
}
}
下面來個post類型的
/// <summary>
/// Post一般處理程序的測試
/// </summary>
public class posthandler : HandlerBase
{
public posthandler()
{
//修改請求為get 方式
base._httpReuqest = base.Context.Request.Form;
}
/// <summary>
/// 乘法操作
/// </summary>
public void Multiply()
{
int a = Convert.ToInt32(_httpReuqest["a"]);
int b = Convert.ToInt32(_httpReuqest["b"]);
PrintSuccessJson((a + b).ToString());
}
/// <summary>
/// 減法操作
/// </summary>
public void Minus()
{
int a = Convert.ToInt32(_httpReuqest["a"]);
int b = Convert.ToInt32(_httpReuqest["b"]);
PrintSuccessJson((a - b).ToString());
}
}
很容易看懂吧,前台的html頁面就不貼了
如果看的同學實在是看不懂 那趕緊猛擊我去下面源碼
還有設計不當之處請各位留言指正哦,共同進步哈
