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 相关文章推荐
为jquery的ajaxfileupload增加附加参数的方法
Mar 04 Javascript
javascript操纵OGNL标签示例代码
Jun 16 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
Jan 28 Javascript
js实现右下角提示框的方法
Feb 03 Javascript
纯JavaScript代码实现文本比较工具
Feb 17 Javascript
JS实现含有中文字符串的友好截取功能分析
Mar 13 Javascript
JavaScript实现简单精致的图片左右无缝滚动效果
Mar 16 Javascript
Angular移动端页面input无法输入的解决方法
Nov 14 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
Feb 07 Javascript
vue从零实现一个消息通知组件的方法详解
Mar 16 Javascript
JS跨浏览器解析XML应用过程详解
Oct 16 Javascript
原生JS封装vue Tab切换效果
Apr 28 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获得用户ip地址的比较不错的方法
2014/02/08 PHP
codeigniter上传图片不能正确识别图片类型问题解决方法
2014/07/25 PHP
php事件驱动化设计详解
2016/11/10 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
2018/03/31 PHP
Javascript实例教程(19) 使用HoTMetal(1)
2006/12/23 Javascript
Stop SQL Server
2007/06/21 Javascript
jquery 插件开发备注
2010/08/27 Javascript
分析了一下JQuery中的extend方法实现原理
2015/02/27 Javascript
jQuery选择器源码解读(六):Sizzle选择器匹配逻辑分析
2015/03/31 Javascript
js正则表达式中exec用法实例
2015/07/23 Javascript
小白谈谈对JS原型链的理解
2016/05/03 Javascript
同步文本框内容JS代码实现
2016/08/04 Javascript
js 实现一些跨浏览器的事件方法详解及实例
2016/10/27 Javascript
bootstrap PrintThis打印插件使用详解
2017/02/20 Javascript
详解webpack进阶之loader篇
2017/08/23 Javascript
gulp教程_从入门到项目中快速上手使用方法
2017/09/14 Javascript
webpack中使用iconfont字体图标的方法
2018/02/22 Javascript
详解Vue2.0配置mint-ui踩过的那些坑
2018/04/23 Javascript
vue 表单输入格式化中文输入法异常问题
2018/05/30 Javascript
解决vue 绑定对象内点击事件失效问题
2018/09/05 Javascript
vue v-for直接循环数字实例
2019/11/07 Javascript
JS图片懒加载的优点及实现原理
2020/01/10 Javascript
[01:30]2016国际邀请赛中国区预选赛神秘商店火爆开启
2016/06/26 DOTA
python实现的文件同步服务器实例
2015/06/02 Python
使用PM2+nginx部署python项目的方法示例
2018/11/07 Python
Django rest framework jwt的使用方法详解
2019/08/08 Python
Django框架反向解析操作详解
2019/11/28 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例
2020/02/11 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
python3.6环境下安装freetype库和基本使用方法(推荐)
2020/05/10 Python
完美解决ARIMA模型中plot_acf画不出图的问题
2020/06/04 Python
python实现录音功能(可随时停止录音)
2020/10/26 Python
使用分层画布来优化HTML5渲染的教程
2015/05/08 HTML / CSS
民主评议政风行风活动心得体会
2014/10/29 职场文书
公务员爱岗敬业心得体会
2016/01/25 职场文书