使用反射机制实现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. Babelfish (STL)

    题目描述 You have just moved from Waterloo to a big city. The people here speak an incomprehensible dial ...

  2. crawler_httpclient代理访问

    public String getDocumentByProxy(String url) throws ClientProtocolException, IOException { DefaultHt ...

  3. HDU 2612 -Find a way (注重细节BFS)

    主题链接:Find a Way 题目不难,前几天做,当时准备写双向BFS的,后来处理细节上出了点问题,赶上点事搁置了.今天晚上重写的,没用双向,用了两次BFS搜索,和双向BFS 道理差点儿相同.仅仅是 ...

  4. 试想一下,在代码学习Swift!

    文件       https://itunes.apple.com/us/book/the-swift-programming-language/id881256329?mt=11       htt ...

  5. CSharp设计模式读书笔记(23):模板方法模式(学习难度:★★☆☆☆,使用频率:★★★☆☆)

    模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中.模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模式角色与结构: 实现代码: using System; ...

  6. TDD

    初识TDD 首先说一下名词解释,TDD,英文名称Test-Driven Development,中文名称测试驱动开发,简单的断下句“测试/驱动/开发”,简单的理解一下,就是测试驱动着开发,大白话就是说 ...

  7. Dojo仪表板

    Dojo它提供了一个良好的仪表板显示器,的影响,如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR0lTU2hpWGlTaGVuZw==/font/ ...

  8. 全新通用编程语言 Def 招募核心贡献者、文档作者、布道师 deflang.org

    先给出官网地址:deflang.org 一句话简介:可扩展编程语言 Def 的目标是将 C++ 的高效抽象和 Lisp 的强大表现力融为一体. 你可以通过阅读 入门教程 .源码 或 测试用例 来简要或 ...

  9. Java 之Integer相等比较

    1.问题提出 今天在和同事讨论问题的时候,无意间谈到了Integer对象的比较,先看下代码: package test; public class IntegerEqual { /** * @para ...

  10. javascript 学习总结(九)面向对象编程

    1.面向对象的工厂方法 function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; ...