在ashx中利用反射+jquery輕松處理ajax 含Demo源碼


   由於jquery的出現,編寫js代碼已經變得異常的平民化,同時現在的web也已經是ajax滿天飛,哪天你自己寫一個web不含ajax的拿不出手

   當然,在.net的控件模式開發中一種去控件化開發已經變的變得更加通用:jquery+ajax+ashx  這種方式更加適用於一些小應用的開發,輕量、簡單、自由

   由於那時候太年輕,剛剛開始這種模式開發的時候 是一個ajax請求一個ashx頁面,這樣的結果可想而知,一個小的權限系統光光ashx文件就幾十個了,而且文件名還大同小異,悲劇。

    后來做了一會兒變聰明了,把相同類別的請求都放到一個ashx文件中,每個請求傳一個請求標志  通過switch來調用相應的請求方法,當然,這樣要比原來好多了,至少沒那么多ashx文件了,但是  每新建一個文件都要去添加switch方法,蛋疼啊  有木有,更加可恥的是 每次增刪改一個請求都要去修改那個可惡的switch語句,煩啊

    后來知道了反射,知道可以用反射來動態調用方法,腦子一轉,哇  好主意,查了相關資料,沒幾分鍾就把這個框架寫了出來,然后百度一搜,次奧,關於這種的都有那么多文章了,本來都不想再寫這篇文章,重復造輪子啊 要被罵的有木有,不過想想代碼都寫了,而且還是自己寫的,寫篇文章紀念一下,而且這個東西感覺比網上的更加方便,實用,嘿嘿。

   下面就是這個handler主心骨雞類的詳解了

    首先在這個雞類中定義幾個默認的參數

    

/// <summary>
        /// 指定過來的http請求類型  主要指定action方法名稱的接收方式 get 或者 post
        /// </summary>
        protected NameValueCollection _httpReuqest = HttpContext.Current.Request.Form;

        /// <summary>
        /// 指定返回頭
        /// </summary>
        protected string _contentType = "text/plain";

        /// <summary>
        /// 指定接收action方法的參數名稱
        /// </summary>
        protected string _actionName = "action";

  主要是定義默認的請求方式  GET或者POST  當然默認是POST,相對安全點嘛,並且個人用的也多,當然這個請求方式在子類中可以把它改掉呢

還有就是請求的返回頭,方法名稱的參數   代碼的注釋里面都寫得很清楚呢

      下面就是動態調用方法的核心代碼啦(再這里給個反射連接的相關知識,不知道的點我哦

//根據指定的請求類型獲取方法名
            string action = this._httpReuqest[this._actionName];
            if (!string.IsNullOrEmpty(action))
            {
                //獲取方法的實例  非靜態 需要Public訪問權限 忽略大小寫
                MethodInfo methodInfo = this.GetType().GetMethod(action, BindingFlags.Instance|BindingFlags.Public|BindingFlags.IgnoreCase);
                if (methodInfo != null)
                {
                    //調用方法
                    methodInfo.Invoke(this, null);
                }
                else
                {
                    throw new ApplicationException(string.Format("沒有找到方法{0}", action));
                }
            }
            else
            {
                throw new ArgumentNullException("沒有找到調用方法參數或者方法名為空");
            }

  核心代碼夠簡單把  其實最核心的就是獲取方法實例,當然該方法,兩句啦 方便吧

      我們看看這個獲取方法實例的代碼

      主要是獲取類中的非靜態,公開訪問,忽略名稱大小寫的方法,當然你如果不放心 其他的方法也被ajax跨域調用了,你可以給該方法的訪問權限設為private或者protected  如果你還是不放心的話  可以喝其他的一樣 自定義一個Attribute特征加在方法頭上,不過個人在這里感覺沒啥必要了

      

核心的都給你們看了 那來看下雞類的全部代碼吧

/// <summary>
    /// Handler請求的基類 用此類動態調用請求的方法
    /// </summary>
    public class HandlerBase : IHttpHandler
    {
        /// <summary>
        /// 指定過來的http請求類型  主要指定action方法名稱的接收方式 get 或者 post
        /// </summary>
        protected NameValueCollection _httpReuqest = HttpContext.Current.Request.Form;

        /// <summary>
        /// 指定返回頭
        /// </summary>
        protected string _contentType = "text/plain";

        /// <summary>
        /// 指定接收action方法的參數名稱
        /// </summary>
        protected string _actionName = "action";

        //獲取當前的http context
        protected HttpContext Context
        {
            get {
                return HttpContext.Current;
            }
        }

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = this._contentType;

            try
            {
                //動態調用方法 當然  你還可以在這里加上是否為同域名請求的判斷
                this.DynamicMethod();
            }
            catch (AmbiguousMatchException amEx)
            {
                this.PrintErrorJson(string.Format("根據該參數{0}找到了多個方法",amEx.Message));
            }
            catch (ArgumentException argEx)
            {
                this.PrintErrorJson("參數異常" + argEx.Message);
            }
            catch (ApplicationException apEx)
            {
                this.PrintErrorJson("程序異常" + apEx.Message);
            }
            
        }

        #region 動態調用方法
        /// <summary>
        /// 動態調用方法
        /// </summary>
        private void DynamicMethod()
        {
            //根據指定的請求類型獲取方法名
            string action = this._httpReuqest[this._actionName];
            if (!string.IsNullOrEmpty(action))
            {
                //獲取方法的實例  非靜態 需要Public訪問權限 忽略大小寫
                MethodInfo methodInfo = this.GetType().GetMethod(action, BindingFlags.Instance|BindingFlags.Public|BindingFlags.IgnoreCase);
                if (methodInfo != null)
                {
                    //調用方法
                    methodInfo.Invoke(this, null);
                }
                else
                {
                    throw new ApplicationException(string.Format("沒有找到方法{0}", action));
                }
            }
            else
            {
                throw new ArgumentNullException("沒有找到調用方法參數或者方法名為空");
            }
        }
        #endregion

        #region 打印Json的相關處理
        /// <summary>
        /// 打印遇到異常的json
        /// </summary>
        /// <param name="msg"></param>
        protected void PrintErrorJson(string msg)
        {
            this.PrintJson("error", msg);
        }

        /// <summary>
        /// 打印成功處理的json
        /// </summary>
        /// <param name="msg"></param>
        protected void PrintSuccessJson(string msg)
        {
            this.PrintJson("success", msg);
        }

        /// <summary>
        /// 打印json
        /// </summary>
        /// <param name="state"></param>
        /// <param name="msg"></param>
        protected void PrintJson(string state, string msg)
        {
            this.Context.Response.Write("{\"state\":\""+state+"\",\"msg\":\"" + msg + "\"}");
        }
        #endregion



        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

夠簡單把,然后寫幾個測試ashx頁面繼承該基類就可以啦

/// <summary>
    /// Get一般處理程序的測試
    /// </summary>
    public class gethandler : HandlerBase
    {
        public gethandler()
        {
            //修改請求為get 方式
            base._httpReuqest = base.Context.Request.QueryString;
        }

        /// <summary>
        /// 加法操作
        /// </summary>
        public void Add()
        {
            int a = Convert.ToInt32(_httpReuqest["a"]);
            int b = Convert.ToInt32(_httpReuqest["b"]);
            PrintSuccessJson((a + b).ToString());
        }

        /// <summary>
        /// 減法操作
        /// </summary>
        private void Minus()
        {
            int a = Convert.ToInt32(_httpReuqest["a"]);
            int b = Convert.ToInt32(_httpReuqest["b"]);
            PrintSuccessJson((a - b).ToString());
        }
        
    }

  下面來個post類型的

/// <summary>
    /// Post一般處理程序的測試
    /// </summary>
    public class posthandler : HandlerBase
    {

        public posthandler()
        {
            //修改請求為get 方式
            base._httpReuqest = base.Context.Request.Form;
        }

        /// <summary>
        /// 乘法操作
        /// </summary>
        public void Multiply()
        {
            int a = Convert.ToInt32(_httpReuqest["a"]);
            int b = Convert.ToInt32(_httpReuqest["b"]);
            PrintSuccessJson((a + b).ToString());
        }

        /// <summary>
        /// 減法操作
        /// </summary>
        public void Minus()
        {
            int a = Convert.ToInt32(_httpReuqest["a"]);
            int b = Convert.ToInt32(_httpReuqest["b"]);
            PrintSuccessJson((a - b).ToString());
        }
    }

  很容易看懂吧,前台的html頁面就不貼了

      如果看的同學實在是看不懂 那趕緊猛擊我去下面源碼

       還有設計不當之處請各位留言指正哦,共同進步哈


免責聲明!

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



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