jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法


Posted in Javascript onSeptember 27, 2011

在某项目中,设计模板字段引擎,采用html+jquery实现,这里的数据就难免需要ajax获取,但是团队对于js掌握不一,所以我写了下面辅助类,可以像ajaxpro一样简化ajax的开发。
代码-jQueryInvokeMethodAttribute (此处只做标示方法处理,所以为空):

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

代码-jQueryAjaxUtility(分注册脚本和调用ajax事件):
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
namespace Green.Utility 
{ 
public class jQueryAjaxUtility 
{ 
public static string AjaxInvokeParam = "AjaxInvoke"; 
public static string AjaxInvokeValue = "1"; 
public static string ResponseCharset = "UTF-8"; 
protected static System.Web.UI.Page Page 
{ 
get 
{ 
return System.Web.HttpContext.Current.Handler as System.Web.UI.Page; 
} 
} 
public static void RegisterClientAjaxScript(Type type) 
{ 
if (Page != null) 
{ 
if (System.Web.HttpContext.Current.Request[AjaxInvokeParam] == AjaxInvokeValue) 
{ 
RegisterAjaxInvokeEvent(type); 
} 
else 
{ 
RegisterAjaxInvokeScript(type); 
} 
} 
} 
protected static void RegisterAjaxInvokeScript(Type type) 
{ 
Page.ClientScript.RegisterClientScriptBlock(type.GetType(), type.GetType().FullName + "_" + typeof(jQueryAjaxUtility).FullName + "_AjaxInvokeDefaultOption", "window.defaultAjaxOption={type:'GET',cache:false, dataType:'text'};", true); 
if (!jQueryUtilityCache.Current.Exists(type)) 
{ 
var methodinfo = type.GetMethods(System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).Where(t => 
{ 
var attrs = t.GetCustomAttributes(typeof(jQueryInvokeMethodAttribute), false); 
if (attrs != null && attrs.Length > 0) 
return true; 
return false; 
}).ToList(); 
if (methodinfo != null && methodinfo.Count > 0) 
{ 
System.Text.StringBuilder sb = new StringBuilder(); 
sb.AppendFormat(" window.{0}=function(){{}}; ", type.Name); 
methodinfo.ForEach(t => 
{ 
var parameters = t.GetParameters().Select(p => p.Name).ToArray(); 
sb.AppendFormat(" {2}.{0} = function ({1} ajaxOption) {{", t.Name, parameters.Count() > 0 ? string.Join(",", parameters) + "," : "", type.Name); 
sb.Append("if(ajaxOption==null||typeof ajaxOption=='undefined'){ajaxOption={};};"); 
var url = Page.Request.RawUrl.IndexOf("?") == -1 ? Page.Request.RawUrl : Page.Request.RawUrl.Substring(0, Page.Request.RawUrl.IndexOf("?") ); 
sb.AppendFormat("ajaxOption.url = '{0}';", url); 
var data = "''"; 
if (parameters.Count() > 0) 
{ 
data = (string.Join(" ", parameters.Select(p => string.Format("'&{0}=' + {0}+", p)).ToArray())); 
data= data.TrimEnd('+'); 
} 
sb.AppendFormat("ajaxOption.data = 'method={1}&rn={4}&{2}={3}'+{0};", data, t.Name, AjaxInvokeParam, AjaxInvokeValue,Guid.NewGuid().ToString()); 
sb.Append("ajaxOption= jQuery.extend(window.defaultAjaxOption,ajaxOption);"); 
sb.Append("jQuery.ajax(ajaxOption);};"); 
}); 
jQueryUtilityCache.Current.AddScript(type, sb.ToString()); 
} 
} 
var script = jQueryUtilityCache.Current.GetScript(type); 
Page.ClientScript.RegisterClientScriptBlock(type.GetType(), type.GetType().FullName + "_" + typeof(jQueryAjaxUtility).FullName + "_AjaxInvoke", script, true); 
} 
protected string GenertorScript(Type type) 
{ 
return string.Empty; 
} 
protected static void RegisterAjaxInvokeEvent(Type type) 
{ 
var Request = System.Web.HttpContext.Current.Request; 
var Response = System.Web.HttpContext.Current.Response; 
var method = Request["method"]; 
if (string.IsNullOrEmpty(method)) 
return; 
Response.Clear(); 
var methodinfo = type.GetMethod(method, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); 
if (methodinfo != null) 
{ 
Response.Charset = ResponseCharset; 
Response.ContentType = string.Join(",", Request.AcceptTypes); 
var param = methodinfo.GetParameters(); 
object[] objs = new object[param.Length]; 
var i = 0; 
param.ToList().ForEach(t => 
{ 
objs[i++] = Convert.ChangeType(Request[t.Name], t.ParameterType); 
}); 
var obj = methodinfo.Invoke(null, objs); 
if (obj != null) 
{ 
//序列化 
if (!obj.GetType().IsValueType && obj.GetType() != typeof(string)) 
{ 
if (Request.AcceptTypes.Contains("text/xml")) 
{ 
Response.Write(Green.Utility.SerializerUtility.XmlSerializer(obj)); 
} 
else if (Request.AcceptTypes.Contains("application/json")) 
{ 
Response.ContentType = "application/json, text/javascript, */*"; 
Response.Write(Green.Utility.SerializerUtility.JsonSerializer(obj)); 
} 
else 
{ 
Response.Write(obj); 
} 
} 
else 
{ 
Response.Write(obj); 
} 
} 
Response.Flush(); 
Response.Close(); 
Response.End(); 
} 
} 
} 
}

为了考虑反射的性能,加入了类级注册脚本方法缓存处理jQueryUtilityCache,具体见demo。
测试:
html:
<form id="form1" runat="server"> 
<div> 
<input id="Button1" type="button" value="button" /> 
</div> 
</form>

后台方法注册Page_Load
Green.Utility.jQueryAjaxUtility.RegisterClientAjaxScript(typeof(_Default));

1:
前台:
_Default.Test("ajax", 
{ 
success: function(e) { 
alert(e); 
}, 
dataType: "text" 
});

后台:
[Green.Utility.jQueryInvokeMethod()] 
public static string Test(string str) 
{ 
return "hello:" + str; 
}

效果:

jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
2:前台ajax:

_Default.TestArrayJson(1, 2, 3, 
{ 
success: function(e) { 
$.each(e, function(i, n) { alert(n); }); 
}, 
dataType: "json" 
})

后台:
[Green.Utility.jQueryInvokeMethod()] 
public static int[] TestArrayJson(int p1, int p2, int p3) 
{ 
return new int[] { p1, p2, p3 }; 
}

效果:

jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法 
3:前台ajax:

_Default.TestArrayxml("key", "value", 
{ 
success: function(e) { 
alert(e.key); 
alert(e.Value); 
}, 
dataType: "json" 
})

后台:
[Green.Utility.jQueryInvokeMethod()] 
public static Test TestArrayxml(string key,string value) 
{ 
return new Test() { key=key,Value=value}; 
}

效果:

jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法

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

jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
附录:代码下载
作者:破 狼 (cnblogs)

Javascript 相关文章推荐
htm调用JS代码
Mar 15 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
May 23 Javascript
jquery使用jquery.zclip插件复制对象的实例教程
Dec 04 Javascript
介绍JavaScript中Math.abs()方法的使用
Jun 14 Javascript
javascript中caller和callee详解
Aug 10 Javascript
JavaScript每天必学之数组和对象部分
Sep 17 Javascript
详解angular脏检查原理及伪代码实现
Jun 08 Javascript
解决echarts的多个折现数据出现坐标和值对不上的问题
Dec 28 Javascript
Vue.js中Line第三方登录api的实现代码
Jun 29 Javascript
Element Input输入框的使用方法
Jul 26 Javascript
在Vue 中获取下拉框的文本及选项值操作
Aug 13 Javascript
vue实现广告栏上下滚动效果
Nov 26 Vue.js
Ext.get() 和 Ext.query()组合使用实现最灵活的取元素方式
Sep 26 #Javascript
一个挺有意思的Javascript小问题说明
Sep 26 #Javascript
Jquery之Ajax运用 学习运用篇
Sep 26 #Javascript
jQuery+CSS 实现随滚动条增减的汽水瓶中的液体效果
Sep 26 #Javascript
在Windows上安装Node.js模块的方法
Sep 25 #Javascript
javascript权威指南 学习笔记之null和undefined
Sep 25 #Javascript
利用JS自动打开页面上链接的实现代码
Sep 25 #Javascript
You might like
php 解压rar文件及zip文件的方法
2014/05/05 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
分享一个Laravel好用的Cache宏
2015/03/02 PHP
js生成随机数之random函数随机示例
2013/12/20 Javascript
js写的方法实现上传图片之后查看大图
2014/03/05 Javascript
jquery任意位置浮动固定层插件用法实例
2015/05/29 Javascript
js鼠标单击和双击事件冲突问题的快速解决方法
2016/07/11 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
教你一步步用jQyery实现轮播器
2016/12/18 Javascript
Bootstrap源码解读导航条(7)
2016/12/23 Javascript
BootStrap Table 后台数据绑定、特殊列处理、排序功能
2017/05/27 Javascript
underscore之function_动力节点Java学院整理
2017/07/11 Javascript
浅谈React + Webpack 构建打包优化
2018/01/23 Javascript
JavaScript实现简单动态进度条效果
2018/04/06 Javascript
解决bootstrap模态框数据缓存的问题方法
2018/08/10 Javascript
vue左侧菜单,树形图递归实现代码
2018/08/24 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
2019/03/07 Javascript
vue使用混入定义全局变量、函数、筛选器的实例代码
2019/07/29 Javascript
使用Taro实现小程序商城的购物车功能模块的实例代码
2020/06/05 Javascript
[02:52]2017DOTA2国际邀请赛中国区预选赛晋级之路
2017/07/03 DOTA
django-crontab 定时执行任务方法的实现
2019/09/06 Python
新手入门学习python Numpy基础操作
2020/03/02 Python
在python中利用pycharm自定义代码块教程(三步搞定)
2020/04/15 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
在终端启动Python时报错的解决方案
2020/11/20 Python
python3.9实现pyinstaller打包python文件成exe
2020/12/13 Python
美国在线家居装饰店:Belle&June
2018/10/24 全球购物
历史学专业大学生找工作的自我评价
2013/10/16 职场文书
小区门卫管理制度
2014/01/29 职场文书
《中彩那天》教学反思
2014/02/22 职场文书
信用卡工作证明模板
2014/09/14 职场文书
华山导游词
2015/02/03 职场文书
学校扫黄打非工作总结
2015/10/15 职场文书
POST提交数据常见的四种方式
2022/01/18 HTML / CSS
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL
Win11任务栏无法正常显示 资源管理器不停重启的解决方法
2022/07/07 数码科技