文章目录

       由于jquery的出现,编写js代码已经变得异常的平民化,同时现在的web也已经是ajax满天飞,哪天你自己写一个web不含ajax的拿不出手
当然,在.net的控件模式开发中一种去控件化开发已经变的变得更加通用:jquery+ajax+ashx 这种方式更加适用于一些小应用的开发,轻量、简单、自由
由于那时候太年轻,刚刚开始这种模式开发的时候 是一个ajax请求一个ashx页面,这样的结果可想而知,一个小的权限系统光光ashx文件就几十个了,而且文件名还大同小异,悲剧。

       后来做了一会儿变聪明了,把相同类别的请求都放到一个ashx文件中,每个请求传一个请求标志 通过switch来调用相应的请求方法,当然,这样要比原来好多了,至少没那么多ashx文件了,但是 每新建一个文件都要去添加switch方法,蛋疼啊 有木有,更加可耻的是 每次增删改一个请求都要去修改那个可恶的switch语句,烦啊

       后来知道了反射,知道可以用反射来动态调用方法,脑子一转,哇 好主意,查了相关资料,没几分钟就把这个框架写了出来,然后百度一搜,次奥,关于这种的都有那么多文章了,本来都不想再写这篇文章,重复造轮子啊 要被骂的有木有,不过想想代码都写了,而且还是自己写的,写篇文章纪念一下,而且这个东西感觉比网上的更加方便,实用,嘿嘿。
下面就是这个handler主心骨鸡类的详解了

       首先在这个基类中定义几个默认的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// <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,相对安全点嘛,并且个人用的也多,当然这个请求方式在子类中可以把它改掉呢
还有就是请求的返回头,方法名称的参数 代码的注释里面都写得很清楚呢

下面就是动态调用方法的核心代码啦(再这里给个反射连接的相关知识,不知道的点我哦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//根据指定的请求类型获取方法名
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特征加在方法头上,不过个人在这里感觉没啥必要了

       核心的都给你们看了 那来看下基类的全部代码吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

/// <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页面继承该基类就可以啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/// <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类型的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

/// <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页面就不贴了

如果看的同学实在是看不懂 那赶紧猛击我去下面源码

还有设计不当之处请各位留言指正哦,共同进步哈

注:此文来自我的博客园


本作品采用[知识共享署名-非商业性使用-相同方式共享 2.5]中国大陆许可协议进行许可,我的博客欢迎复制共享,但在同时,希望保留我的署名权kubiCode,并且,不得用于商业用途。如您有任何疑问或者授权方面的协商,请给我留言

文章目录