<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      asp.net webForm也可以這樣用Ajax -- My Ajax Framework

             對于asp.net WebForm項目,進行Ajax操作大概有三種方式:web服務(.asmx文件)  ,  一般處理程序(.ashx)和  一些Ajax控件。

      對于.net提供的ajax控件,暫且不說,只說另外兩種方式,都需要引入額外的代碼文件對Ajax進行操作(asmx和ashx,且web服務還要引入一個cs文件與之對應),假如要對Example.aspx這個頁面添加一些自定義的Ajax操作,并且這些Ajax操作并不會在別的頁面上用到,如此不得不引入額外的代碼文件完成這個操作,假如這個Ajax操作很簡單,只需要一個簡單的函數(shù)就可以執(zhí)行,那豈不是很麻煩的過程嗎?如此一來,隨著項目中Ajax操作的增多,ashx和asmx文件都會隨著時間的增長而增長,項目的維護也會隨之加倍。為什么我們不能把Ajax操作的后臺代碼直接放在Example.aspx對應的Example.aspx.cs文件里 ? 如果能這樣做,以上兩種煩惱都會迎刃而解,不是嗎?

            于是,按照以上思路,實現(xiàn)了如下Ajax框架。先來看這個框架的實現(xiàn)機制:

       

            上圖是自己畫的一個縮減版IIS接收到一個aspx請求的HttpApplication管線和asp.net Page在執(zhí)行ProcessRequest()方法中的頁面生命周期的部分事件。Page本身是繼承自IHttpHandler接口,IHttpHandler提供了一個重要的約束方法ProcessRequest,該方法是對接收到的信息(HttpContext)進行具體的處理同樣,一般處理程序和web服務也實現(xiàn)了自己的IHttpHandler,并以此提供一些Ajax服務。具體的操作過程請自行查找MSDN。

             原理是在頁面生命周期開始的第一個事件PreInit進行一些處理,一旦發(fā)現(xiàn)劫持到的請求是一個ajax請求,那么利用C#的反射來調用aspx.cs中定義的方法,執(zhí)行完方法之后,調用Response.End()方法,調用這個方法會直接跳到管線的EndRequest事件,從而結束請求,這樣就無需走一些沒有必要的頁面生命周期的步驟,從而完成一個Ajax操作。如果發(fā)現(xiàn)是一個正常的操作,那么就走正常流程。

       

      下面以一個簡單例子說明該Ajax框架的使用:

      1.       添加一個解決方案

      2.       新建一個 Default.aspx 頁面

      3.       在Default.aspx.cs頁面中創(chuàng)建一個被調用的測試方法:

                public List<string>  TestAjaxMethod(int a, string b, float c)
                {
                       return new List<string> { a.ToString(), b, c.ToString() };
                }

      4.      在Default.aspx中寫一個Ajax請求

                PowerAjax.AsyncAjax(‘TestAjaxMethod’, [1, 2, "333","sss"], function (SucceessResponse) {
                        // 成功后的代碼
                });

            PowerAjax.js是用Jquery專門為這個框架封裝的一個及其簡單的JS類庫,這個類庫中有兩個主要的方法:PowerAjax.AsyncAjax和PowerAjax.SyncAjax,一個提供同步操作,一個    提供異步操作,參數(shù)有三個:

            第一個參數(shù)是即將操作在aspx.cs的Ajax方法的名字(用名字反射方法)。

            第二個參數(shù)是一個以數(shù)組形式組成參數(shù)列表數(shù)據(jù)。

            第三個參數(shù)是操作成功之后執(zhí)行執(zhí)行的回調方法,與c#中的委托一個道理。

            以下為這個簡單JS庫的代碼:

      var PowerAjax = function () { }
      PowerAjax.__Private = function () { }
      
      // 進行異步操作
      PowerAjax.AsyncAjax = function (methodName, paramArray, success) {
          PowerAjax.__Private.Ajax(methodName, paramArray, success, true);
      }
      
      // 進行的是同步操作
      PowerAjax.SyncAjax = function (methodName, paramArray, success) {
          PowerAjax.__Private.Ajax(methodName, paramArray, success, false);
      }
      
      PowerAjax.__Private.Ajax = function (methodName, paramArray, success, isAsync) {
          var data = {};
          switch (paramArray.length) {
              case 0:
                  data = { 'isAjaxRequest': true, 'MethodName': methodName };
                  break;
              case 1:
                  data = { 'isAjaxRequest': true, 'MethodName': methodName, "param0": paramArray[0] };
                  break;
              case 2:
                  data = { 'isAjaxRequest': true, 'MethodName': methodName, "param0": paramArray[0], "param1": paramArray[1] };
                  break;
              case 3:
                  data = { 'isAjaxRequest': true, 'MethodName': methodName, "param0": paramArray[0], "param1": paramArray[1], "param2": paramArray[2] };
                  break;
              case 4:
                  data = { 'isAjaxRequest': true, 'MethodName': methodName, "param0": paramArray[0], "param1": paramArray[1], "param2": paramArray[2], "param3": paramArray[3] };
                  break;
              case 5:
                  data = { 'isAjaxRequest': true, 'MethodName': methodName, "param0": paramArray[0], "param1": paramArray[1], "param2": paramArray[2], "param3": paramArray[3], "param4": paramArray[4] };
                  break;
          }
      
          var url = document.location.href;
          $.ajax({
              type: "post",
              url: url,
              data: data,
              async: isAsync,
              datatype: "json",
              contentType: "application/x-www-form-urlencoded; charset=UTF-8",
              success: function (response) {
                  success(response);
              },
              error: function (response) {
                  if (response.status == 500) {
                      var errorMessage = response.responseText;
                      var errorTitle = errorMessage.substring(errorMessage.indexOf("<title>") + 7, errorMessage.indexOf("</title>"))
                      throw new Error("服務器內部錯誤:" + errorTitle);
                  }
              }
          });
      }
      

        

      5.       更改Default.aspx.cs的繼承頁面為AjaxBasePage              

      public partial class _Default : AjaxBasePage

      6.        主要基類:AjaxBasePage

      如下代碼:

      public class AjaxBasePage : System.Web.UI.Page
      {
          /// <summary>
          /// 是否是一個ajax請求。
          /// </summary>
          public bool IsAjaxRequest { get; private set; }
      
          /// <summary>
          ///  如果是Ajax請求,劫持頁面生命周期的PreInit的事件,直接返回Response
          /// </summary>
          protected override void OnPreInit(EventArgs e)
          {
              AjaxRequest ajaxRequest = AjaxRequest.GetInstance(Request.Form);
              this.IsAjaxRequest = ajaxRequest.IsAjaxRequest;
      
              if (this.IsAjaxRequest)
              {
                  AjaxApplication ajaxApplication = new AjaxApplication(this, ajaxRequest);
                  ajaxApplication.EndRequest();
              }
              else
              {
                  // 如果不是Ajax請求,繼續(xù)執(zhí)行頁面生命周期的剩余事件
                  base.OnPreInit(e);
              }
          }
      }

       

              該類重寫了PreInit方法,判斷請求是否是一個Ajax請求。通過AjaxRequest類接收并處理接收到的請求,提取出一些有效的數(shù)據(jù),比如說是否是一個Ajax請求,方法的名字,參數(shù)列表(AjaxParameter類)。

              至于AjaxParameter類,內部用的數(shù)據(jù)結構其實是一個字典,并使用索引來提供對數(shù)據(jù)的方便訪問,提供一個Count屬性,方便獲取參數(shù)的個數(shù)。     如下代碼:

      public class AjaxParameter
          {
              private IDictionary<int, string> m_DictionaryParamsData = new Dictionary<int, string>();
      
              /// <summary>
              /// 返回參數(shù)的個數(shù)。
              /// </summary>
              public int Count
              {
                  get
                  {
                      return this.m_DictionaryParamsData.Count;
                  }
              }
      
              /// <summary>
              /// 索引具體參數(shù)的值。
              /// </summary>
              /// <param name="index"></param>
              /// <returns></returns>
              public string this[int index]
              {
                  get
                  {
                      if (index >= 5 || index < 0)
                      {
                          throw new NotSupportedException("請求方法的參數(shù)的個數(shù)限制為:0-5");
                      }
                      return this.m_DictionaryParamsData[index];
                  }
              }
      
              public AjaxParameter(IDictionary<int, string> paramsData)
              {
                  this.m_DictionaryParamsData = paramsData;
              }
          }
      

        

               AjaxRequest類的設計思路其實是模仿HttpContext設計,HttpContext能夠從基礎的http請求報文分析出以后處理將要用到的數(shù)據(jù)(response,request,session,cookie等等)數(shù)據(jù),而AjaxRequest通過分析Ajax的Post請求的數(shù)據(jù)域Data分析出各種以后會用到的數(shù)據(jù)。如下是該類的代碼:

      public class AjaxRequest
          {
              private Dictionary<int, string> m_DictionaryParamsData = new Dictionary<int, string>();
              private AjaxParameter m_AjaxParameter;
              private int m_Count = 0;
      
              #region 屬性
              /// <summary>
              /// 是否是一個Ajax請求。
              /// </summary>
              public bool IsAjaxRequest { get; private set; }
      
              /// <summary>
              /// 請求的方法名字。
              /// </summary>
              public string MethodName { get; private set; }
      
              /// <summary>
              /// 參數(shù)數(shù)據(jù)。
              /// </summary>
              public AjaxParameter Parameters
              {
                  get { return this.m_AjaxParameter; }
              }
              #endregion
      
              #region 構造函數(shù)
              private AjaxRequest(NameValueCollection nameValueCollection)
              {
                  this.IsAjaxRequest = nameValueCollection["isAjaxRequest"] == "true";
                  if (this.IsAjaxRequest)
                  {
                      this.MethodName = nameValueCollection["MethodName"];
      
                      foreach (string value in nameValueCollection)
                      {
                          string formKey = string.Format("param{0}", this.m_Count);
                          if (nameValueCollection[formKey] != null)
                          {
                              this.m_DictionaryParamsData.Add(this.m_Count, nameValueCollection[formKey]);
                              this.m_Count++;
                          }
                      }
                      m_AjaxParameter = new AjaxParameter(this.m_DictionaryParamsData);
                  }
              }
      
              #endregion
      
              #region 實例方法
              public static AjaxRequest GetInstance(NameValueCollection nameValueCollection)
              {
                  return new AjaxRequest(nameValueCollection);
              }
              #endregion
      
              #region ToString
              public override string ToString()
              {
                  return this.MethodName;
              }
              #endregion
          }

              通過分析AjaxRequest的屬性IsAjaxRequest可判斷是否為Ajax請求,若該請求為一個Ajax請求,那么創(chuàng)建一個AjaxApplication實例,在創(chuàng)建AjaxApplication實例的過程中會利用當前頁面和AjaxRequest提供的數(shù)據(jù)進行實際方法的調用(反射),該類是執(zhí)行Ajax方法的核心類,其中會判斷是否讀取的到的方法是一個有效的方法,并判斷從JS中AjaxApplication傳入的參數(shù)類型的有效性,目前只提供對以下13中參數(shù)提供支持,如下:

      (String、Boolean、Int32、Int64、UInt32、UInt64、Single、Double、Decimal、DateTime、DateTimeOffset、TimeSpan、Guid)

               如果方法中出現(xiàn)非以上類型,將會拋出異常。為了方便Ajax的調試,在JS前段類庫中我會對異常進行處理,并拋出Error,Error信息有效的截取了繼承自Exception的拋出信息,至于如何獲    得更加詳細的JS調試信息,以后JS庫中可能會做提供更加詳細的調用信息,畢竟框架是在改進中進行的。如下是AjaxApplication類的具體代碼:

      public class AjaxApplication
          {
              private AjaxBasePage m_AjaxBasePage;
              private object m_ResponseData;
      
              public AjaxApplication(AjaxBasePage ajaxBasePage, AjaxRequest ajaxRequest)
              {
                  this.m_AjaxBasePage = ajaxBasePage;
                  Type ajaxBasePageType = ajaxBasePage.GetType();
                  MethodInfo methodInfo = ajaxBasePageType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)
                                              .FirstOrDefault(item => item.Name == ajaxRequest.MethodName);
                  object[] parameterData = this.GetParameterData(ajaxRequest, methodInfo);
      
                  if (methodInfo.IsStatic)
                  {
                      this.m_ResponseData = methodInfo.Invoke(null, parameterData);
                  }
                  else
                  {
                      this.m_ResponseData = methodInfo.Invoke(ajaxBasePage, parameterData);
                  }
              }
      
              /// <summary>
              /// 獲取參數(shù)數(shù)據(jù)。
              /// </summary>
              private object[] GetParameterData(AjaxRequest ajaxRequest, MethodInfo methodInfo)
              {
                  if (methodInfo != null)
                  {
                      ParameterInfo[] parameterInfos = methodInfo.GetParameters();
      
                      if (parameterInfos.Length > 5)
                      {
                          throw new NotSupportedException("最多支持5個參數(shù)");
                      }
      
                      if (parameterInfos.Length > ajaxRequest.Parameters.Count)
                      {
                          throw new ArgumentException("缺少參數(shù)!");
                      }
      
                      List<object> parameterData = new List<object>(parameterInfos.Length);
                      for (int i = 0; i < parameterInfos.Length; i++)
                      {
                          ParameterInfo parameterInfo = parameterInfos[i];
                          string paramValue = ajaxRequest.Parameters[i];
      
                          try
                          {
                              parameterData.Add(ParseAjaxParameter(paramValue, parameterInfo));
                          }
                          catch (FormatException)
                          {
                              string format = string.Format("傳入靜態(tài)方法 {0} 的第 {1} 個(從0開始計數(shù))參數(shù)類型不匹配,應該為 {2} 類型 請檢查!", methodInfo.Name, i, parameterInfo.ParameterType.Name);
                              throw new FormatException(format);
                          }
                      }
                      return parameterData.ToArray();
                  }
                  else
                  {
                      throw new InvalidOperationException("沒有發(fā)現(xiàn)此方法,請檢查該方法簽名(方法必須為public)");
                  }
              }
      
              /// <summary>
              /// 類型轉換。支持 String、Boolean、Int32、Int64、UInt32、UInt64、Single、Double、Decimal、DateTime、DateTimeOffset、TimeSpan、Guid
              /// </summary>
              private object ParseAjaxParameter(string ajaxParameterValue, ParameterInfo parameterInfo)
              {
                  object obj;
                  if (parameterInfo.ParameterType == typeof(String))
                  {
                      obj = ajaxParameterValue;
                  }
                  else if (parameterInfo.ParameterType == typeof(Boolean))
                  {
                      obj = bool.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(Int32))
                  {
                      obj = Int32.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(UInt32))
                  {
                      obj = UInt32.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(UInt64))
                  {
                      obj = UInt64.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(Single))
                  {
                      obj = Single.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(Double))
                  {
                      obj = Double.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(Decimal))
                  {
                      obj = Decimal.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(DateTime))
                  {
                      obj = DateTime.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(DateTimeOffset))
                  {
                      obj = DateTimeOffset.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(TimeSpan))
                  {
                      obj = TimeSpan.Parse(ajaxParameterValue);
                  }
                  else if (parameterInfo.ParameterType == typeof(Guid))
                  {
                      obj = Guid.Parse(ajaxParameterValue);
                  }
                  else
                  {
                      throw new NotSupportedException("方法參數(shù)類型不支持!");
                  }
                  return obj;
              }
      
              /// <summary>
              /// 結束頁面生命周期,同時直接執(zhí)行應用程序生命周期的EndRequest事件。
              /// </summary>
              public void EndRequest()
              {
                  HttpResponse response = this.m_AjaxBasePage.Page.Response;
                  response.ContentType = "application/json";
                  response.Clear();
                  JavaScriptSerializer jsonSerializer2 = new JavaScriptSerializer();
                  response.Write(jsonSerializer2.Serialize(new JsonResponse { IsSuccess = true, Message = "處理成功", ResponseData = this.m_ResponseData }));
                  response.End();
              }
          }
      

        

              當初始化了一個AjaxApplication實例后, 可以調用該實例的EndRequest()方法,來結束Ajax請求。該方法內部最后調用Response.End()方法來結束頁面生命周期和大部分管線事件。

      并用JsonResponse類來封裝返回數(shù)據(jù)。

      public class JsonResponse
      {
          public bool IsSuccess { get; set; }
          public string Message { get; set; }
          public object ResponseData { get; set; }
      }

               該類最后一個參數(shù)即承載了調用方法的返回值,為一個Object類型,也就是說,框架可以支持任何類型的返回值,當然該類型可以被序列化。

      7.        回過頭來再看Ajax請求,針對返回值可以這樣用:

                      PowerAjax.AsyncAjax('TestAjaxMethod', [1, 2, "333", "sss"], function (SucceessResponse) {
                          if (SucceessResponse.IsSuceess) {
                              alert("恭喜,該ajax方法調用成功!");
                              Process(SucceessResponse.ResponseData); // 處理返回的數(shù)據(jù),這里可能需要你自己實現(xiàn)了,因為我無法判斷你要返回的是什么東西,這是個Object
                          } else {
                              alert("這是操作錯誤奧,不是內部異常,內部異常的拋出會我內部會處理的!");
                              alert("錯誤信息:" + SucceessResponse.Message);
                          }
                      });
                  });

      以上是試水的東西,希望各位大牛指正。

      posted @ 2013-03-28 16:02  純粹的郭子  閱讀(7992)  評論(40)    收藏  舉報
      主站蜘蛛池模板: 日本一区二区精品色超碰| 国产精品麻豆va在线播放| 国产女人喷潮视频免费| 欧美成人aaa片一区国产精品| 99久久无色码中文字幕| 日本一本正道综合久久dvd| 久久天天躁狠狠躁夜夜躁2012| 亚洲午夜福利网在线观看| 欧美人成精品网站播放| 精品一区二区三区无码视频| 加勒比无码人妻东京热 | 人人超人人超碰超国产 | 国产精品视频亚洲二区| 色九月亚洲综合网| 女人与牲口性恔配视频免费| 久久99九九精品久久久久蜜桃| 亚洲一区二区三区激情在线| 国产亚洲av嫩草久久| 好男人社区神马在线观看www| 国产精品亚洲а∨天堂2021| 亚洲日本欧洲二区精品| 久久妇女高潮喷水多| 国产欲女高潮正在播放| 久久本道综合久久伊人| 他掀开裙子把舌头伸进去添视频| 视频一区二区三区四区不卡| 国产福利社区一区二区| 久久久久国产精品人妻| 看全色黄大黄大色免费久久| 精品视频一区二区福利午夜| 免费中文熟妇在线影片| 加勒比亚洲天堂午夜中文| 日韩av片无码一区二区不卡| 久久综合伊人77777| 国产h视频在线观看| 女人与公狍交酡女免费| 久久久av男人的天堂| 国产愉拍精品手机| 久久夜色精品国产噜噜亚洲sv| 无码一区二区三区久久精品| 国产丝袜在线精品丝袜不卡|