程序集;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());
}
}