我们都知道在AjaxPro的方法AjaxPro.Utility.RegisterTypeForAjax(typeof(所在类的类名));会将标记有[Ajax.AjaxMethod]方法注册在客户端。在某项目中,设计模板字段引擎,采用html+jquery实现,这里的数据就难免需要ajax获取,但是团队对于js掌握不一,所以我写了下面辅助类,可以像ajaxpro一样简化ajax的开发。

代码-jQueryInvokeMethodAttribute (此处只做标示方法处理,所以为空):

  1. [AttributeUsage(AttributeTargets.Method, AllowMultiple=false,Inherited=false)]   
  2.     public class jQueryInvokeMethodAttribute : Attribute   
  3.     {   
  4.     } 

代码-jQueryAjaxUtility(分注册脚本和调用ajax事件):View Code

  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Text;   
  5.  
  6. namespace Green.Utility   
  7. {   
  8.     public class jQueryAjaxUtility   
  9.     {   
  10.         public static string AjaxInvokeParam = "AjaxInvoke";   
  11.         public static string AjaxInvokeValue = "1";   
  12.         public static string ResponseCharset = "UTF-8";   
  13.  
  14.         protected static System.Web.UI.Page Page   
  15.         {   
  16.             get   
  17.             {   
  18.                 return System.Web.HttpContext.Current.Handler as System.Web.UI.Page;   
  19.             }   
  20.         }   
  21.  
  22.         public static void RegisterClientAjaxScript(Type type)   
  23.         {   
  24.             if (Page != null)   
  25.             {   
  26.                 if (System.Web.HttpContext.Current.Request[AjaxInvokeParam] == AjaxInvokeValue)   
  27.                 {   
  28.                     RegisterAjaxInvokeEvent(type);   
  29.                 }   
  30.                 else   
  31.                 {   
  32.                     RegisterAjaxInvokeScript(type);   
  33.                 }   
  34.             }   
  35.         }   
  36.  
  37.         protected static void RegisterAjaxInvokeScript(Type type)   
  38.         {   
  39.  
  40.             Page.ClientScript.RegisterClientScriptBlock(type.GetType(), type.GetType().FullName + "_" + typeof(jQueryAjaxUtility).FullName + "_AjaxInvokeDefaultOption""window.defaultAjaxOption={type:'GET',cache:false, dataType:'text'};"true);   
  41.  
  42.             if (!jQueryUtilityCache.Current.Exists(type))   
  43.             {   
  44.                 var methodinfo = type.GetMethods(System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).Where(t =>   
  45.                 {   
  46.                     var attrs = t.GetCustomAttributes(typeof(jQueryInvokeMethodAttribute), false);   
  47.                     if (attrs != null && attrs.Length > 0)   
  48.                         return true;   
  49.                     return false;   
  50.                 }).ToList();   
  51.  
  52.                 if (methodinfo != null && methodinfo.Count > 0)   
  53.                 {   
  54.                     System.Text.StringBuilder sb = new StringBuilder();   
  55.                     sb.AppendFormat(" window.{0}=function(){{}}; ", type.Name);   
  56.                     methodinfo.ForEach(t =>   
  57.                     {   
  58.                         var parameters = t.GetParameters().Select(p => p.Name).ToArray();   
  59.                         sb.AppendFormat(" {2}.{0} = function ({1} ajaxOption) {{", t.Name, parameters.Count() > 0 ? string.Join(",", parameters) + "," : "", type.Name);   
  60.                         sb.Append("if(ajaxOption==null||typeof ajaxOption=='undefined'){ajaxOption={};};");   
  61.                         var url = Page.Request.RawUrl.IndexOf("?") == -1 ? Page.Request.RawUrl : Page.Request.RawUrl.Substring(0, Page.Request.RawUrl.IndexOf("?") );   
  62.                         sb.AppendFormat("ajaxOption.url = '{0}';", url);   
  63.                         var data = "''";   
  64.                         if (parameters.Count() > 0)   
  65.                         {   
  66.                             data = (string.Join(" ", parameters.Select(p => string.Format("'&{0}=' + {0}+", p)).ToArray()));   
  67.                            data= data.TrimEnd('+');   
  68.                         }   
  69.                         sb.AppendFormat("ajaxOption.data = 'method={1}&rn={4}&{2}={3}'+{0};", data, t.Name, AjaxInvokeParam, AjaxInvokeValue,Guid.NewGuid().ToString());   
  70.  
  71.                         sb.Append("ajaxOption= jQuery.extend(window.defaultAjaxOption,ajaxOption);");   
  72.                         sb.Append("jQuery.ajax(ajaxOption);};");   
  73.                     });   
  74.                     jQueryUtilityCache.Current.AddScript(type, sb.ToString());   
  75.                 }   
  76.             }   
  77.             var script = jQueryUtilityCache.Current.GetScript(type);   
  78.             Page.ClientScript.RegisterClientScriptBlock(type.GetType(), type.GetType().FullName + "_" + typeof(jQueryAjaxUtility).FullName + "_AjaxInvoke", script, true);   
  79.         }   
  80.  
  81.         protected string GenertorScript(Type type)   
  82.         {   
  83.  
  84.             return string.Empty;   
  85.         }   
  86.  
  87.         protected static void RegisterAjaxInvokeEvent(Type type)   
  88.         {   
  89.  
  90.             var Request = System.Web.HttpContext.Current.Request;   
  91.             var Response = System.Web.HttpContext.Current.Response;   
  92.             var method = Request["method"];   
  93.             if (string.IsNullOrEmpty(method))   
  94.                 return;   
  95.             Response.Clear();   
  96.             var methodinfo = type.GetMethod(method, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);   
  97.             if (methodinfo != null)   
  98.             {   
  99.                 Response.Charset = ResponseCharset;   
  100.                 Response.ContentType = string.Join(",", Request.AcceptTypes);   
  101.                 var param = methodinfo.GetParameters();   
  102.                 object[] objs = new object[param.Length];   
  103.                 var i = 0;   
  104.                 param.ToList().ForEach(t =>   
  105.                 {   
  106.                     objs[i++] = Convert.ChangeType(Request[t.Name], t.ParameterType);   
  107.                 });   
  108.                 var obj = methodinfo.Invoke(null, objs);   
  109.                 if (obj != null)   
  110.                 {   
  111.                     //序列化   
  112.                     if (!obj.GetType().IsValueType && obj.GetType() != typeof(string))   
  113.                     {   
  114.                         if (Request.AcceptTypes.Contains("text/xml"))   
  115.                         {   
  116.                             Response.Write(Green.Utility.SerializerUtility.XmlSerializer(obj));   
  117.                         }   
  118.                         else if (Request.AcceptTypes.Contains("application/json"))   
  119.                         {   
  120.                             Response.ContentType = "application/json, text/javascript, */*";   
  121.                             Response.Write(Green.Utility.SerializerUtility.JsonSerializer(obj));   
  122.                         }   
  123.                         else   
  124.                         {   
  125.                             Response.Write(obj);   
  126.                         }   
  127.  
  128.                     }   
  129.                     else   
  130.                     {   
  131.                         Response.Write(obj);   
  132.                     }   
  133.                 }   
  134.  
  135.                 Response.Flush();   
  136.                 Response.Close();   
  137.                 Response.End();   
  138.             }   
  139.         }   
  140.  
  141.     }   
  142. }  
  143. 复制代码 

为了考虑反射的性能,加入了类级注册脚本方法缓存处理jQueryUtilityCache,具体见demo。

测试:

  1. html:  
  2.  
  3. <form id="form1" runat="server">   
  4.     <div>   
  5.         <input id="Button1" type="button" value="button" />   
  6.     </div>   
  7.     </form> 

后台方法注册Page_Load

  1. Green.Utility.jQueryAjaxUtility.RegisterClientAjaxScript(typeof(_Default));  
  2. 1:  
  3.  
前台:
  1. _Default.Test("ajax",   
  2.                              {   
  3.                                  success: function(e) {   
  4.                                      alert(e);   
  5.                                  },   
  6.                                  dataType: "text"   
  7.                              });  
后台:
  1. [Green.Utility.jQueryInvokeMethod()]   
  2.    public static string Test(string str)   
  3.    {   
  4.        return "hello:" + str;   
  5.    }   
效果:

2:

前台ajax:

  1. _Default.TestArrayJson(1, 2, 3,   
  2.               {   
  3.                   success: function(e) {                                    
  4.                       $.each(e, function(i, n) { alert(n); });   
  5.                   },   
  6.                   dataType: "json"   
  7.               })   
后台:
  1. [Green.Utility.jQueryInvokeMethod()]   
  2. public static int[] TestArrayJson(int p1, int p2, int p3)   
  3. {   
  4.     return new int[] { p1, p2, p3 };   
  5. }  
  6.    
效果:

3:

前台ajax:

_
  1. Default.TestArrayxml("key", "value",   
  2.             {   
  3.                 success: function(e) {   
  4.                     alert(e.key);   
  5.                     alert(e.Value);   
  6.                 },   
  7.                 dataType: "json"   
  8.             })  
后台:
  1. [Green.Utility.jQueryInvokeMethod()]   
  2.     public static Test TestArrayxml(string key,string value)   
  3.     {   
  4.         return new Test() { keykey=key,Value=value};   
  5.     }  
效果:

最后看看FireBug中ajax http头信息:

其他资料jQuery目录:  我jQuery系列之目录汇总

附录:代码下载