我们写ajax时,可能惯用的方法就是在一个handler里面通过传进来的参数switch不同的方法来,这种做法当方法较少的时候显得应付自
如,但方法数量庞大的时候,这样做就会显得代码非常冗杂了。于是我们会想到反射来做。
项目结构如下图所示:
代码如下:
Demo.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Demo.aspx.cs" Inherits="Demo" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<script src="js/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
$(function(){
var url = "handler/Handler.ashx";
var t="TestOther";
var pt = ["i","f"];
var pv = ["1","1223.234"];
$.post(url,{t:t,pt:pt,pv:pv},function(data){
alert(data);
});
});
-->
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
Handler.ashx:
<%@ WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web;
using System.Reflection;
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
string mothod = context.Request.Form["t"];
string pt = context.Request.Form["pt"];
string pv = context.Request.Form["pv"];
string retValue = "";
if (pt != null && pv != null && pt != "" && pv != "" && pt != "null" && pv != "null")
{
string[] pta = pt.Split(',');
string[] pva = pv.Split(',');
if (pta.Length == pva.Length)
{
retValue = ReflectMethod(mothod, pta, pva);
}
else
{
//参数个数不相等
retValue = "参数个数不相等";
}
}
else
{
//参数为空
retValue = ReflectMethod(mothod, null, null);
}
context.Response.Write(retValue);
}
/// <summary>
/// 反射程序集中的方法
/// </summary>
/// <param name="mothod">方法名</param>
/// <param name="pt">参数类型数组</param>
/// <param name="pv">参数值数组</param>
/// <returns></returns>
private string ReflectMethod(string mothod, string[] pt, string[] pv)
{
string retValue = "";
//读取选择指定的dll文件
string strPath = HttpContext.Current.Server.MapPath(@"../DLLFile/Demo.dll");
string NameSpace = "Demo.Demo";
try
{
//加载指定的程序集
Assembly assembly = Assembly.LoadFrom(strPath);
//返加程序集中的一个指定的对象,如果要返回所有对象,则用GetTypes()返回一个Typt对象的数组.
Type T = assembly.GetType(NameSpace);
//参数类型
Type[] type = null;
object[] obj = null; //这里一定要跟类型对应,否则会造成参数转换错误
if (pt != null && pt.Length > 0)
{
type = new Type[pt.Length];
obj = new object[pt.Length];
for (int i = 0; i < type.Length; i++)
{
obj[i] = pv[i];
type[i] = GetType(pt[i],i, ref obj);
}
}
if (type == null) //参数类型不能是null值,必须是一个数组,当为null时,赋值为一个空数组
type = new Type[0] { };
//返回方法信息(公共方法)
MethodInfo mi = T.GetMethod(mothod, type);
//根据前面type类型创建一个对象
object o = Activator.CreateInstance(T);
//通过MethodInfo对象的Invoke方法,动态调用此方法,参数o是因为实例方法需要在调用时有一个实例存在
retValue = (string)mi.Invoke(o, obj);
}
catch (Exception ex)
{
retValue = ex.Message;
}
return retValue;
}
/// <summary>
///
/// </summary>
/// <param name="pt"></param>
/// <param name="index"></param>
/// <param name="obj"></param>
/// <returns></returns>
private Type GetType(string pt,int index,ref object[] obj)
{
switch (pt)
{
case "i": obj[index] = int.Parse(obj[index].ToString()); return typeof(int);
case "f": obj[index] = float.Parse(obj[index].ToString()); return typeof(float);
case "s": return typeof(string);
case "b": obj[index] = bool.Parse(obj[index].ToString()); return typeof(bool);
case "d": obj[index] = DateTime.Parse(obj[index].ToString()); return typeof(DateTime);
default: return null;
}
}
public bool IsReusable {
get {
return false;
}
}
}
Demo.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace Demo
{
public class Demo
{
public string GetDemo()
{
return "调用了一个没有参数的方法";
}
public string GetDemo(string arg1)
{
return "调用了一个参数的方法,参数是:" + arg1;
}
public string GetDemo(string arg1, string arg2)
{
return "调用了一个参数的方法,第一个参数是:" + arg1 + "第二个参数是:" + arg2;
}
public string TestOther(int arg1, float arg2)
{
return "int:"+arg1.ToString()+";float:"+arg2.ToString();
}
}
}
因为本代码只是提供一种思路,或者一种入门的基础的东西,只要稍作改造,很多东西可以做得更好,比如GetType这个方法显得有点杂了,但我暂时没有想到好方法,如果有高手可以指教一下,也许会做得更好。