使用反射机制实现jQuery调用ashx类中的指定方法
使用反射机制实现jQuery调用ashx类中的指定方法
近期用asp.net做个小网站,但又不喜欢使用asp.net的服务器端控件,经过一番思量后确定前端采用原始的html、后台采用Linq to Sql与数据库交互,Linq上面创建一业务逻辑层,而web前端通过使用jQuery的ajax方法异步调用asp.net的一般处理程序(handler),实现与后台的业务逻辑层交互,至此大方向开发框架确立,只是细节上jQuery调用ashx有点小麻烦,一次只能调用一个ashx类,如此这般,一个模块增、删、改、查一套功能下来我不是得创建多个handler类?项目虽小,但这样做下来势必会产生很多ashx文件,对代码管理与阅读相当的不便,如果一个完整的功能模块下来只对应一个handler类该多好,通过调用同一个handler类执行不同方法来完成一模块中的不同的功能,就像java的strus框架的Action那样,经过思考隐约觉得使用反射机制可以实现上述想法,然后又百度了一下参考前人经验,经过实验确实可行,做了如下总结:
(1).使用反射机制的Invoke方法需要引用System.Reflection类。在使用jQuery的Ajax方法时,固定一个传值参数用来向handler类传送要执行的指定方法,参数可以随便命,但确定下来后就不能更改,我这里统一命名为"Action"。
(2).为节省劳动力与成本,避免重复编码我创建名为"BaseHandler.ashx"的基类,在这个类里边除了实现反射外,同时提供了一些通用方法以方便继承它的子类调用,所有的Handler类均继承该类。主要代码如下:
/// <summary>
/// 通过反射机制执行指定方法
/// </summary>
/// <param name="context"></param>
public void ProcessRequest(HttpContext context)
{
const string MESSAGE = "无法获取参数值或参数值不正确。";
string strAction = "";
Object[] objParameter;
Type[] objParamType;
Type objMethodType;
MethodInfo objMethod;
//获取参数传递(Acion为要执行的方法名)
strAction = GetRequest(context, "Action");
if (strAction != "")
{
//获取调用类的类型
objMethodType = this.GetType();
//设置方法参数值,并存入数组(在这里将HttpContext作为方法的参数)
objParameter = new object[1];
objParameter[0] = context;
//获取参数的数据类型
objParamType = new Type[1];
objParamType[0] = objParameter[0].GetType();
//获取指定的方法对象
objMethod = objMethodType.GetMethod(strAction, objParamType);
//如果存在,则进行调用并返回给前台页面
if (objMethod != null)
{
context.Response.Write((string)objMethod.Invoke(this, objParameter));
}
}
else
{
//异常提示信息
context.Response.Write(MESSAGE);
}
}
/// <summary>
///
/// </summary>
public bool IsReusable
{
get
{
return false;
}
}
/// <summary>
/// 获取指定键值的参数值
/// </summary>
/// <param name="context">HttpContext</param>
/// <param name="key">指定键</param>
/// <returns>String</returns>
public String GetRequest(HttpContext context, String key)
{
String strRet = "";
//如果指定键值的参数存在,则获取
if (context.Request[key] != null)
{
strRet = context.Request[key].ToString();
}
return strRet;
}

1 /// <summary>
2 /// 通过反射机制执行指定方法
3 /// </summary>
4 /// <param name="context"></param>
5 public void ProcessRequest(HttpContext context)
6 {
7 const string MESSAGE = "无法获取参数值或参数值不正确。";
8
9 string strAction = "";
10 Object[] objParameter;
11 Type[] objParamType;
12 Type objMethodType;
13 MethodInfo objMethod;
14
15 //获取参数传递(Acion为要执行的方法名)
16 strAction = GetRequest(context, "Action");
17 if (strAction != "")
18 {
19 //获取调用类的类型
20 objMethodType = this.GetType();
21
22 //设置方法参数值,并存入数组(在这里将HttpContext作为方法的参数)
23 objParameter = new object[1];
24 objParameter[0] = context;
25
26 //获取参数的数据类型
27 objParamType = new Type[1];
28 objParamType[0] = objParameter[0].GetType();
29
30 //获取指定的方法对象
31 objMethod = objMethodType.GetMethod(strAction, objParamType);
32
33 //如果存在,则进行调用并返回给前台页面
34 if (objMethod != null)
35 {
36 context.Response.Write((string)objMethod.Invoke(this, objParameter));
37 }
38 }
39 else
40 {
41 //异常提示信息
42 context.Response.Write(MESSAGE);
43 }
44 }
45
46 /// <summary>
47 ///
48 /// </summary>
49 public bool IsReusable
50 {
51 get
52 {
53 return false;
54 }
55 }
56
57 /// <summary>
58 /// 获取指定键值的参数值
59 /// </summary>
60 /// <param name="context">HttpContext</param>
61 /// <param name="key">指定键</param>
62 /// <returns>String</returns>
63 public String GetRequest(HttpContext context, String key)
64 {
65 String strRet = "";
66
67 //如果指定键值的参数存在,则获取
68 if (context.Request[key] != null)
69 {
70 strRet = context.Request[key].ToString();
71 }
72
73 return strRet;
74 }

这里有几个注意点:在实现ProcessRequest方法中,页面参数传值的获取上我这里只获取了Action参数的值:strAction = GetRequest(context, "Action");也就是要执行的方法名,而在实际应用中传值参数不止一个,不同的调用方法有不同的参数,当然在这里也可以全部获取存入数组中最后交给Invoke,但个人觉得没有必要在这在获取所有的传值,仅Action足已,因为Action是固定的,其他的参数可以交由要处理的Action方法去接收,怎么接入?我把HttpContext作为要执行的方法的参数传进去了:objParameter[0] = context;这样做的好处是代码清晰,分工明确,业务逻辑清晰简单。
(3).再看BaseHandler的子类,假设我们现在对用户管理这一模块来实现,该模块有用户登录、添加、删除、修改、列表等功能,将这些功能的实现方法统一放在UserHandler.ashx类中,在该类中只做了简单用户登录演示,其他功能都可触类旁通,代码如下:
/// <summary>
/// UserHandler 的摘要说明
/// </summary>
public class UserHandler : BaseHandler
{
/// <summary>
/// 用户登录处理
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public String Login(HttpContext context)
{
String strAccount = "";
String strPassword = "";
String strRet;
try
{
//获取页面传值
strAccount = GetRequest(context, "Account");
strPassword = GetRequest(context, "Password");
if (strAccount != "" && strPassword != "")
{
//简单起见,仅返回传递过来的用户账号与密码
//在实际应用中利用传递过来的参数值调用业务逻辑层的方法来完成客户端的请求
strRet = String.Format("账号:{0},密码:{1}", strAccount, strPassword);
}
else
{
//返回提示信息
strRet = "未能正确获取参数!";
}
return strRet;
}
catch (Exception ex)
{
throw ex;
}
}
}

1 /// <summary>
2 /// UserHandler 的摘要说明
3 /// </summary>
4 public class UserHandler : BaseHandler
5 {
6 /// <summary>
7 /// 用户登录处理
8 /// </summary>
9 /// <param name="context"></param>
10 /// <returns></returns>
11 public String Login(HttpContext context)
12 {
13 String strAccount = "";
14 String strPassword = "";
15 String strRet;
16
17 try
18 {
19
20 //获取页面传值
21 strAccount = GetRequest(context, "Account");
22 strPassword = GetRequest(context, "Password");
23
24 if (strAccount != "" && strPassword != "")
25 {
26 //简单起见,仅返回传递过来的用户账号与密码
27 //在实际应用中利用传递过来的参数值调用业务逻辑层的方法来完成客户端的请求
28 strRet = String.Format("账号:{0},密码:{1}", strAccount, strPassword);
29 }
30 else
31 {
32 //返回提示信息
33 strRet = "未能正确获取参数!";
34 }
35
36 return strRet;
37 }
38 catch (Exception ex)
39 {
40 throw ex;
41 }
42 }
43
44 }

在这里我们只有一个Login方法参数为HttpContext类,而在这个方法里边我们可以通过HttpContext类再次获取除了Action以外的页面传值,代码应该是相当清晰的,注意在这里不需要再实现ProcessRequest与IsReusable方法,可以直接删去。
(4).Html网站前端调用UserHandler.ashx代码:
<script type="text/javascript">
$(document).ready(function () {
$("#btnLogin").click(function () {
var account;
var password;
account = $("#txtUserName").val();
password = $("#txtPassword").val();
$.ajax({
type: "POST",
async: true,
url: "Handler/UserHandler.ashx",
dataType: "text",
data: { Action: "Login", Account: account, Password: password },
success: function (data) {
alert(data);
},
error: function (xhr) {
alert(xhr.statusText);
return false;
}
});
});
});
</script>

1 <script type="text/javascript">
2 $(document).ready(function () {
3 $("#btnLogin").click(function () {
4 var account;
5 var password;
6
7 account = $("#txtUserName").val();
8 password = $("#txtPassword").val();
9
10 $.ajax({
11 type: "POST",
12 async: true,
13 url: "Handler/UserHandler.ashx",
14 dataType: "text",
15 data: { Action: "Login", Account: account, Password: password },
16 success: function (data) {
17 alert(data);
18 },
19 error: function (xhr) {
20 alert(xhr.statusText);
21 return false;
22 }
23 });
24 });
25 });
26 </script>

调用URL:UserHandler.ashx,传值参数:data: { Action: "Login", Account: account, Password: password },除了Login方法外还有账号与密码,坚持一切从简原则,回调函数只是alert了一下返回结果,从UserHandler.ashx的Login方法中不难看出,如果调用成功alert的应该是:"账号:你输入的账号,密码:你输入的密码"。到此一条路线已打通,其他的功能实现照样画葫芦就行。
(5).关于方法重载,我在百度的时候也看到过类似的介绍,也给了我很多的启示,但很多人都问到方法重载的问题如何解决,就没有下文了,其实实现重载也很简单,在同一方法里边根据你获取参数的多少与不同,间接的去调用重载方法不就解决问题了吗?
使用反射机制实现jQuery调用ashx类中的指定方法的更多相关文章
- Java中是否可以调用一个类中的main方法?
前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...
- PHP通过反射方法调用执行类中的私有方法
PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 下面我们演示一下如何通过反射,来调用执行一个类中的私有方法: <?php //MyClass这个类中包 ...
- 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考原贴地址:https://blog.csdn.net/clementad/article/details/47339519 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Trans ...
- 【转】在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考 原文链接 @Transactional does not work on method level 描述 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational) ...
- Java反射机制demo(五)—获得并调用一个类中的方法
Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...
- java 中利用反射机制获取和设置实体类的属性值
摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...
- 反射、反射机制、类加载、Class类专题复习
一.反射概念 1.反射机制允许程序在执行期借助于ReflectionAPI取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法.反射在设计模式和框架底层都会用到. 2. ...
- asp.net中js和jquery调用ashx的不同方法分享,需要的朋友可以参考一下
asp.net中js和jquery调用ashx的不同方法分享,需要的朋友可以参考一下 =============js================ 复制代码代码如下: var xhr = n ...
- @Transactional 同一个类中无事务方法a()内部调用有事务方法b()的问题
https://blog.csdn.net/u010235716/article/details/90171802 1. 事务的4种特性 序号 参数 含义1 原子性(Atomicity) ...
随机推荐
- hdu 1251(字典树)
题目链接:http://acm.hdu.edu.cn/status.php?user=NYNU_WMH&pid=1251&status=5 Trie树的基本实现 字母树的插入(Inse ...
- 使用Mockito进行单元测试【2】—— stub 和 高级特性[转]
一篇中介绍了Mockito的基本信息,现在接着介绍Mockito强大的stub功能 2. Mockito使用实例 5. 对连续的调用进行不同的返回 (iterator-style stubbing) ...
- 2015傅富泰写——STRING权
前两天我在丰富的祝福大福参加了宣讲会.并参加了笔试,最后,一个大问题,我在这里谈解决方案,关于这些问题的含义是这样的,您只能使用c图书馆,实现一个功能void MakeString(char *pSt ...
- js之with
网上找资料的时候看到有js代码里出现了大量的with语句,有点好奇,这里做下总结: 1)简要说明 with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性. ...
- C# 跨线程呼叫控制
在C# 应用程序开发, 我们经常要UI作线程分开,防止界面停止响应. 同一时候我们又须要在工作线程中更新UI界面上的控件, 以下介绍几种经常使用的方法 阅读文件夹 线程间操作无效 第一种办法:禁止编 ...
- oracle_恢复流程图
网上看到一个很好的数据恢复检查图片,共享给大家
- Sqlserver2012 评估期已过解决问题
Sqlserver2012评估期已过问题解决 一.背景: 因为之前安装sqlserver2012忘记输入序列号,如今出现评估期已过的问题,前几天忙活半天,才解决,发现网 上叙述都非常凌乱,并且仅仅有 ...
- 【高德地图API】从零开始学高德JS API(三)覆盖物——标注|折线|多边形|信息窗口|聚合marker|麻点图|图片覆盖物
原文:[高德地图API]从零开始学高德JS API(三)覆盖物——标注|折线|多边形|信息窗口|聚合marker|麻点图|图片覆盖物 摘要:覆盖物,是一张地图的灵魂.有覆盖物的地图,才是完整的地图.在 ...
- 【百度地图API】情人节求爱大作战——添加标注功能
原文:[百度地图API]情人节求爱大作战--添加标注功能 任务描述: 2月2日是除夕,2月14立马来!即将到来的情人节,你想送TA一份什么礼物呢? 不如,在你们居住的地方,画个大大的桃心,表达你对TA ...
- MEF框架在Silverlight中应用(15)
原文:MEF框架在Silverlight中应用(15) MEF框架在Silverlight中应用 代码下载 MEF框架是微软提供的一个插件框架.应用概括为一句话:输入,输出,组合.下面是具体在Silv ...