使用反射机制实现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) ...
随机推荐
- CSS定位与层叠
position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位 ...
- hdu 3449 (有依赖的01背包)
依赖背包 事实上,这是一种树形DP,其特点是每个父节点都需要对它的各个儿子的属性进行一次DP以求得自己的相关属性. fj打算去买一些东西,在那之前,他需要一些盒子去装他打算要买的不同的物品.每一个盒子 ...
- oracle_五千万数据插入测试
--创建表 tab_a -- create table tab_a (id int primary key not null,pid int); --创建序列 /** create sequence ...
- JavaScript & XML
原文:JavaScript & XML 检测浏览器能力特性 //检测浏览器是否支持DOM2级XML var hasXmlDom = document.implementation.hasFea ...
- DYNAMICRESOLUTION | NODYNAMICRESOLUTION
有时候开启OGG进程的时候较慢,可能是由于须要同步的表太多,OGG在开启进程之前会将须要同步的表建立一个记录而且存入到磁盘中,这样就须要耗费大量的时间.OGG同一时候也提供了DYNAMICRESOLU ...
- js小记 function 的 length 属性
原文:js小记 function 的 length 属性 [1,2,3]., ,这个略懂js的都知道. 但是 eval.length,RegExp.length,"".toStr ...
- Swift语言指南(三)--语言基础之整数和浮点数
原文:Swift语言指南(三)--语言基础之整数和浮点数 整数 整数指没有小数的整数,如42,-23.整数可以是有符号的(正数,零,负数),也可以是无符号的(正数,零). Swift提供了8,16,3 ...
- http协议报头信息和主体鉴别
http协议报头信息和主体是使用一个空行分开.这是什么空行?简单的说,那是,\r\n\r\n. 所以会server数据的回归\r\n\r\n结果分离,一个是标题信息.它是一个消息的文本. C#例如,下 ...
- 在Mac OS X 10.8中配置Apache+PHP+MySQL
在Mac OS X 10.8中配置Apache+PHP+MySQL的内容包括: 配置Apache 配置PHP 安装MySQL 配置PHPAdmin 设置数据库默认字符集 一. 配置Apache 1. ...
- ASP.NET 依赖注入。
ASP.NET 依赖注入. http://www.it165.net/pro/html/201407/17685.html 我在网上看到了这篇文章,这边文章主要说的方法就是通过读取配置文件来解决依赖注 ...