程序集;Assembly中包含了可以在 CLR(Common Language Runtime)中執行的代碼。所有的.NET應用程序都是由一個或多個assembly組成的,不論你在創建一個Console,WinForms,WebForms應用程序或者一個類 庫時,實際上你都是在創建assembly。甚至.NET本身也是通過assembly來實現其功能。一個assembly可以由一個或者多個文件組成,簡單來說,你可以把assembly理解成一個邏輯上的DLL。每個assembly必須有一個單獨的執行入口如DllMain, WinMain, Main等。Assembly也有一套配置(Deploying)和版本控制(Versioning)的機制。和傳統的DLL 等COM組件相比,.NET有着明顯的優點(我們將在後面看到),另外它還可以避免一些諸如DLL兼容性等問題的困擾(地獄般的困擾,譯者深有體會),並可以大大簡化配置上存在的問題。
由於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());
}
} |