被解放的阿賈克斯


   前一段時間做一個系統功能,頁面用到比較多的異步處理---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的問題,有的話望同志們告知分享。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM