我们都知道在ajaxpro的方法ajaxpro.utility.registertypeforajax(typeof(所在类的类名));会将标记有[ajax.ajaxmethod]方法注册在客户端。在某项目中,设计模板字段引擎,采用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;
}
效果:
2:
前台ajax:
_default.testarrayjson(1, 2, 3,
{
success: function(e) {
$.each(e, function(i, n) { alert(n); });
},
datatype: "json"
})
public static int[] testarrayjson(int p1, int p2, int p3)
return new int[] { p1, p2, p3 };
3:
_default.testarrayxml("key", "value",
success: function(e) {
alert(e.key);
alert(e.value);
},
datatype: "json"
})
public static test testarrayxml(string key,string value)
return new test() { key=key,value=value};
最后看看firebug中ajax http头信息: