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 相关文章推荐
对象特征检测法判断浏览器对javascript对象的支持
Jul 25 Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
Feb 29 Javascript
基于jQuery实现仿51job城市选择功能实例代码
Mar 02 Javascript
javascript原生ajax写法分享
Apr 10 Javascript
由简入繁实现Jquery树状结构的方法(推荐)
Jun 10 Javascript
Jquery给当前页或者跳转后页面的导航栏添加选中后样式的实例
Dec 08 Javascript
js时间戳和c#时间戳互转方法(推荐)
Feb 15 Javascript
理解Angular的providers给Http添加默认headers
Jul 04 Javascript
简单实现js轮播图效果
Jul 14 Javascript
Angular2+国际化方案(ngx-translate)的示例代码
Aug 23 Javascript
javascript 通过键名获取键盘的keyCode方法
Dec 31 Javascript
ES6字符串的扩展实例
Dec 21 Javascript
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中通过smtp发邮件的类,测试通过
2007/01/22 PHP
PHP中uploaded_files函数使用方法详解
2011/03/09 PHP
windows服务器中检测PHP SSL是否开启以及开启SSL的方法
2014/04/25 PHP
PHP数组编码gbk与utf8互相转换的两种方法
2016/09/01 PHP
php版微信自动登录并获取昵称的方法
2016/09/23 PHP
CI框架实现框架前后端分离的方法详解
2016/12/30 PHP
PHP sdk实现在线打包代码示例
2020/12/09 PHP
又一个图片自动缩小的JS代码
2007/03/10 Javascript
网页图片延时加载的js代码
2010/04/22 Javascript
javascript中的document.open()方法使用介绍
2013/10/09 Javascript
动态载入js提高网页打开速度的方法
2014/07/04 Javascript
JavaScript中模拟实现jsonp
2015/06/19 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖动基本操作
2015/11/30 Javascript
老生常谈javascript变量的命名规范和注释
2016/09/29 Javascript
微信小程序之picker日期和时间选择器
2017/02/09 Javascript
关于Sequelize连接查询时inlude中model和association的区别详解
2017/02/27 Javascript
webpack3之loader全解析
2017/10/26 Javascript
vue中element 上传功能的实现思路
2018/07/06 Javascript
微信小程序实现省市区三级地址选择
2020/06/21 Javascript
全面了解JavaScript的作用域链
2019/04/03 Javascript
vue $set 给数据赋值的实例
2019/11/09 Javascript
[03:07]完美世界DOTA2联赛PWL DAY10 决赛集锦
2020/11/11 DOTA
Python基于pyCUDA实现GPU加速并行计算功能入门教程
2018/06/19 Python
Python算法的时间复杂度和空间复杂度(实例解析)
2019/11/19 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
2020/02/26 Python
Pytorch十九种损失函数的使用详解
2020/04/29 Python
HTML5进度条特效
2014/12/18 HTML / CSS
html5用video标签流式加载的实现
2020/05/20 HTML / CSS
elf彩妆英国官网:e.l.f. Cosmetics英国(美国平价彩妆品牌)
2017/11/02 全球购物
护士自荐信
2013/10/25 职场文书
体育教师自荐信范文
2013/12/16 职场文书
2015年前台接待工作总结
2015/05/04 职场文书
银行大堂经理培训心得体会
2016/01/09 职场文书
MySQL 自定义变量的概念及特点
2021/05/13 MySQL
粗暴解决CUDA out of memory的问题
2021/05/22 Python
Spring Boot DevTools 全局配置学习指南
2022/03/31 Java/Android