前一段时间做一个系统功能,页面用到比较多的异步处理---AJAX,所以在后台出现了类似的下面的代码:


string action = Request["action"] == null ? "" : Request["action"].Replace("'", "");string a1 = Request["a1"] == null ? "" : Request["a1"].Replace("'", "");string a2 = Request["a2"] == null ? "" : Request["a2"].Replace("'", "");switch(action){case "action1":action1();break;case "action2":action2(a1, a2);break;case "action3":break;case "action4":break;case "action5":break;case "action6":break;default:break;}
写着写着,发现代码太长了,看着不顺眼,最近有时间,想了一个办法,可以用到反射的处理方法。
先说一下思路,大概就是根据ajax的一个参数值(值也就是方法名),来反射调用的方法,这样就可以直接找到方法了,但重要的是还要解决方法的参数传递问题,
这里我采用的是,反射获取方法的参数名,然后根据参数名去查找ajax路径中传递的参数值(ajax中的参数名必需和方法的参数名一样),这样方法的参数问题也就解决了。好了,思路有了就实现吧!let's go!
前端:


<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script><script type="text/javascript">$(function () {$.ajax({url: "WebForm2.aspx?action=action1",data: { r: new Date().getTime() },success: function (msg) {alert(msg);}})$.ajax({url: "WebForm2.aspx?action=action2",data: { a1: "1", a2: "c2", r: new Date().getTime() },success: function (msg) {alert(msg);}})});</script>
后端:


protected void Page_Load(object sender, EventArgs e){string action = Request["action"] == null ? "" : Request["action"].Replace("'", ""); //获取当前类下的所有方法MethodInfo method = this.GetType().GetMethod(action);//,BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic if (method != null){ParameterInfo[] par = method.GetParameters();method.Invoke(this, getParameterValue(par));}}public void action1(){Response.Clear();Response.Write("1");Response.End();}public void action2(string a1, string a2){Response.Clear();Response.Write("a1:"+a1+"a2:"+a2);Response.End();}/// <summary>/// 根据参数列表获取url参数值/// </summary>/// <param name="parameter">方法参数列表</param>/// <returns>参数值数组</returns>public object[] getParameterValue(ParameterInfo[] parameter){object[] p = new object[parameter.Length];int i = 0;foreach (ParameterInfo par in parameter){string s = Request[par.Name] == null ? "" : Request[par.Name].Replace("'", "");p[i] = s; //ConvertSimpleType(s, par.ParameterType);转换类型,解决为string类型以外的参数i++;}return p;}
这样就可以不用写switch case ,之前有用过一种webserivce方式,也可以解决掉这个问题,但因为webMethod方法,必需要是静态的公共方法,才能成功被调用,
这样就有一定的局限性了,
不过还是把这种方式贴出来供大家参考下,
前端:


$(function () { $.ajax({type: "post",async: false,url: "WebForm3.aspx/action1",data: null,dataType: "json",contentType: "application/json",success: function (msg) {alert(msg.d);}})$.ajax({type: "post",async: false,url: "WebForm3.aspx/action2",data: '{ "a1": "1", "a2": "2" }', //这里一定要写成json字符串形式,否则无效dataType: "json",contentType: "application/json",success: function (msg) {alert(msg.d);}})});
后端:
[WebMethod]public static string action1(){return "1";}[WebMethod]public static string action2(string a1,string a2){return "2";}
用这种方式的话,需要注意的是如果项目是3.5框架以下的,需要在webconfig文件中添加如下代码
<!--JQuery ajax调用asp.net的webMethod问题 2.0--><httpModules><add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpModules>
其实这种方式,可以将ajax封装起来调用


function AjaxMethod(methodName, data, onSuccess, onError) {try {var o = $.extend({}, { onSuccess: onSuccess, onError: onError });$.ajax({type: 'post',async: false,url: $.trim(methodName),data: data,dataType: 'json',contentType: "application/json",success: function (events) {var event = events.d;if (onSuccess) o.onSuccess(event);},error: function (event) { if (onError) o.onError(event); }});} catch (e) {// $.messager.alert("提示", "在操作的过程中出现了异常!原因:" + e.responseText.Message); }}//调用方式AjaxMethod("WebForm3.aspx/action1", null, function (msg) { alert(1); })//这里如果封装的脚本放在引用脚本中,需要注意路径问题,确保脚本能找到页面
大概就这些了,后期还写过解决参数中存在sting类型以外的方法(如参数中有int 类型的),或是重载的方法的解决方案,但感觉没什么必要,因此也就不贴出来了!还得废话一番这种反射的方式肯定没有直接调用方法的执行效率高,不过用于ajax中完成可以忽略。网上有朋友,写了可以高效反射的解决方案。有兴趣的朋友可以去
百度或Google。
PS:不知道这种解决方式有没有什么弊端,也不知道还有没其它什么方式来解决这种类似switch case的问题,有的话望同志们告知分享。