被解放的阿贾克斯

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

View Code
            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!

前端:

View Code
<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>

后端:

View Code
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方法,必需要是静态的公共方法,才能成功被调用,

这样就有一定的局限性了,

不过还是把这种方式贴出来供大家参考下,

前端:

View Code
$(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封装起来调用

View Code
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的问题,有的话望同志们告知分享。

posted @ 2013-04-27 23:53  码到程功  阅读(1955)  评论(10编辑  收藏  举报