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 相关文章推荐
使用EXT实现无刷新动态调用股票信息
Nov 01 Javascript
jQuery select控制插件
Aug 17 Javascript
JS将秒换成时分秒实现代码
Sep 03 Javascript
jquery+ajax+C#实现无刷新操作数据库数据的简单实例
Feb 08 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
Sep 28 Javascript
基于JavaScript实现一定时间后去执行一个函数
Dec 14 Javascript
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
Dec 14 Javascript
JS解决移动web开发手机输入框弹出的问题
Mar 31 Javascript
vue中使用localstorage来存储页面信息
Nov 04 Javascript
解决Vue调用springboot接口403跨域问题
Sep 02 Javascript
layui 富文本编辑器和textarea值的相互传递方法
Sep 18 Javascript
JS中一些高效的魔法运算符总结
May 06 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
深入了解php4(1)--回到未来
2006/10/09 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
2011/08/23 Javascript
JavaScript中的object转换成number或string规则介绍
2014/12/31 Javascript
jQuery添加删除DOM元素方法详解
2016/01/18 Javascript
easyui validatebox验证
2016/04/29 Javascript
js 获取图像缩放后的实际宽高,位置等信息
2017/03/07 Javascript
js循环map 获取所有的key和value的实现代码(json)
2018/05/09 Javascript
原生js封装的ajax方法示例
2018/08/02 Javascript
解决vue初始化项目时,一直卡在Project description上的问题
2019/10/31 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
antd form表单数据回显操作
2020/11/02 Javascript
vue+elementUI动态增加表单项并添加验证的代码详解
2020/12/17 Vue.js
朴素贝叶斯算法的python实现方法
2014/11/18 Python
为Python的web框架编写MVC配置来使其运行的教程
2015/04/30 Python
python安装PIL模块时Unable to find vcvarsall.bat错误的解决方法
2016/09/19 Python
python爬虫之百度API调用方法
2017/06/11 Python
Python3之简单搭建自带服务器的实例讲解
2018/06/04 Python
Anaconda2 5.2.0安装使用图文教程
2018/09/19 Python
如何利用Python分析出微信朋友男女统计图
2019/01/25 Python
python实现给微信指定好友定时发送消息
2019/04/29 Python
12个Python程序员面试必备问题与答案(小结)
2019/06/24 Python
详解python调用cmd命令三种方法
2019/07/08 Python
解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程
2020/03/10 Python
使用Python爬取弹出窗口信息的实例
2020/03/14 Python
解决django的template中如果无法引用MEDIA_URL问题
2020/04/07 Python
Keras之fit_generator与train_on_batch用法
2020/06/17 Python
解析HTML5的存储功能和web SQL的相关操作方法
2016/02/19 HTML / CSS
Marc Jacobs官方网站:美国奢侈品牌
2017/08/29 全球购物
审计专业自荐信范文
2014/04/21 职场文书
船舶工程技术专业求职信
2014/08/07 职场文书
会计主管竞聘书
2015/09/15 职场文书
导游带团欢迎词
2015/09/30 职场文书
SQL IDENTITY_INSERT作用案例详解
2021/08/23 MySQL
日本十大血腥动漫,那些被禁播的动漫盘点
2022/03/21 日漫
用PYTHON去计算88键钢琴的琴键频率和音高
2022/04/10 Python