使用反射机制实现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).关于方法重载,我在百度的时候也看到过类似的介绍,也给了我很多的启示,但很多人都问到方法重载的问题如何解决,就没有下文了,其实实现重载也很简单,在同一方法里边根据你获取参数的多少与不同,间接的去调用重载方法不就解决问题了吗?

 
 
 
标签: jQueryajaxASP.NETashxhandler反射

使用反射机制实现jQuery调用ashx类中的指定方法的更多相关文章

  1. Java中是否可以调用一个类中的main方法?

    前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...

  2. PHP通过反射方法调用执行类中的私有方法

    PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 下面我们演示一下如何通过反射,来调用执行一个类中的私有方法: <?php //MyClass这个类中包 ...

  3. 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法

    参考原贴地址:https://blog.csdn.net/clementad/article/details/47339519 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Trans ...

  4. 【转】在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法

    参考 原文链接 @Transactional does not work on method level 描述 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational) ...

  5. Java反射机制demo(五)—获得并调用一个类中的方法

    Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...

  6. java 中利用反射机制获取和设置实体类的属性值

    摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...

  7. 反射、反射机制、类加载、Class类专题复习

    一.反射概念 1.反射机制允许程序在执行期借助于ReflectionAPI取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法.反射在设计模式和框架底层都会用到. 2. ...

  8. asp.net中js和jquery调用ashx的不同方法分享,需要的朋友可以参考一下

    asp.net中js和jquery调用ashx的不同方法分享,需要的朋友可以参考一下     =============js================ 复制代码代码如下: var xhr = n ...

  9. @Transactional 同一个类中无事务方法a()内部调用有事务方法b()的问题

    https://blog.csdn.net/u010235716/article/details/90171802 1. 事务的4种特性       序号 参数 含义1 原子性(Atomicity) ...

随机推荐

  1. hdu 3460 Ancient Printer

    Problem Description The contest is beginning! While preparing the contest, iSea wanted to print the ...

  2. Oracle内存管理(五)

    [深度分析--eygle]学习笔记 1.4. 2其他内存组件 Large Pool-大池是SGA的一个可选组件,通经常使用于共享server模式(MTS). 并行计算或 RMAN的备份恢复等操作. J ...

  3. android控制文件:ViewPager+Fragment+GridView使用(与AndroidQuery框架结合)

    最近我看到一个AndroidQuery该框架.里面Demo,有一个屏幕,让博主喜欢.很顺利的左右滑动,感觉非常好,所以拿来和大家分享一下.看看结果图.: 从图中能够看出.上面的布局是一个Layout里 ...

  4. 10分钟学会Linux

    10分钟学会Linux有点夸张,可是能够让一个新手初步熟悉Linux中最重要最主要的知识,本文翻译的英文网页在众多Linux入门学习的资料中还是很不错的. 英文地址:http://freeengine ...

  5. Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds解

    产生了一个解决这个问题的方法是在项目部署到tomcat比长45第二,当项目是比较大的,框架复杂的问题经常发生. 解决方法非常easy,找到以下这个路径中 workspace\.metadata\.pl ...

  6. iOS10收集IDFA,植入第三方广告[终结]--ADMob

    [PS: 前段时间,公司做ASO推广,需要在应用中收集IDFA值,跟广告平台做交互!于是有了这个需求--] 1.首先,考虑了一下情况(自己懒 -_-#),就直接在首页上写了一个Banner,循环加载广 ...

  7. Flex 日志管理

    在Flex中调试方法有两种: 一是用trace()函数,在flex builder中进行调试: 二是用logTarget类,例如以下代码: // Create a target. var logTar ...

  8. Web API 2 对 CORS 的支持

    Web API 2 对 CORS 的支持 CORS概念 跨域资源共享 (CORS) 是一种万维网联合会 (W3C) 规范(通常被认为是 HTML5 的一部分),它可让 JavaScript 克服由浏览 ...

  9. WebService对跨域的支持

    WebService对跨域的支持 跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问.也就是说JavaScript只能访问和操作自己域下的资源, ...

  10. Unix/Linux环境C编程新手教程(41) C语言库函数的文件操作具体解释

     上一篇博客我们解说了怎样使用Linux提供的文件操作函数,本文主要解说使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #in ...