假如这个世界上只剩下你一个人,当你正坐在屋子里的时候,这时突然响起了敲门声...

asp.net Ajax 终极解决方案

上一篇 / 下一篇  2008-05-01 18:00:37

查看( 94 ) / 评论( 2 )
ajax 在目前 web 领域已广泛应用,其真正核心只不过是一个封装好了的 js 库。最五花八门的莫过于 asp.net 的控件,我个人认为 ajax 只是一个轻量级的东西,根本没有必要将它写成服务器组件,如 ajax.net、AjaxControlToolkit 等。所以我一直视这些组件为垃圾。。。
a1r&]r*]k0 ITPUB个人空间 gx sl_3J
以下说明我为什么不认同 ajax 的相关组件:
*w8Cs\_9ovPe(vC0 ITPUB个人空间wF W p9u\7K#^)K9C
1、将 ajax 封装得太死,出现问题难于调试;
IW_X~G0 2、组件过于臃肿,太多没有用的功能;ITPUB个人空间 \o0t4f~3o Q7U!|
3、依赖性太强,少一样不可,如 webform;ITPUB个人空间KpP|*e\
ITPUB个人空间\~s(K9tm^
传统的 ajax 应用到项目中,会出现由于项目的 ajax 应用太多,服务端的 ajax 响应函数难于管理,我们到底要把这些响应函数部署在什么位置?ITPUB个人空间 bx4u gV)M
ITPUB个人空间+\ wh N ~MT!P
假如ITPUB个人空间(y.j2x+D@)h h
index.aspx 里有三个 ajax 响应函数,我们可以把这三个响应函数放在 index.aspx 中,并于 Page_Load 事件中根据参数不同来调用这些函数。ITPUB个人空间M a,o7u H5x9ZA\
index.aspx 里还使用了 abc.ascx,这个控件里面也用到了 ajax,那么 abc.ascx 里的响应函数又应该放在哪里?index.aspx 中吗?如果 index2.aspx 中也用到了 abc.ascx,难道还要复制 index.aspx 的处理函数到 index2.aspx,这样肯定不行;
R,C7h"tRaQ:L*Q0 我们可以新建一个 ajax.aspx 来处理所有的 ajax 响应,php/asp 都可以这样做。这样管理还是不理想,
/P l4O)r/mYp0 最理想的管理方法应该是页面、控件与响应函数集成。ICallBackEventHandler 可以做到,但是它依赖 webform,假如你的页面中没有一个 <form runat="server">,则会失效。
5A|c,ZIU e;G P0 问题回归到如体使用轻量级 ajax,并实现页面/控件与 ajax 响应函数集成。ITPUB个人空间9H5AU+C+k{(`
ITPUB个人空间1X vEb,B [.J0H!I
Reflector 查看 System.Web.UI.Page 里面处理 ICallBackEventHandler 模块后,我们可以这样做:ITPUB个人空间'aTY_9aF_%u
ITPUB个人空间W+A#P9E"P!mKV Y
1、所有页面继承 BasePage;ITPUB个人空间M1N1\.TPEK%o+d,m4t$[
2、BasePage 继承 System.Web.UI.Page,重写 BasePage.OnLoad;
6j_*Q)q,N#H:~)MEH0 3、实现 AjaxHandlerITPUB个人空间R]1s1jF xe/|
4、添加 Ajax 类,实现 Ajax.Register 静态方法
q.}.oU{;^0 ITPUB个人空间hfQ]_c,H B0M
代码如下:ITPUB个人空间hNIy:n8bN
public class BasePage : Page {ITPUB个人空间:o+H ]2[.Z t`8]
    protected override void OnLoad(EventArgs e) {ITPUB个人空间 Qocz%pKF
        AjaxHandler();
F ESQ1uPx6E~ ~0         base.OnLoad(e);
/C)^9~R\Tb0     }
,G!L*S5K/U/| m:h0 ITPUB个人空间R QI5[%Bh c!F9]
    ajax handler#region ajax handlerITPUB个人空间f_)] i!Y
    //我喜欢用 json 格式数据来返回给客户端处理
y4im/r"o0     protected void AjaxHandler() {
G7WC$y_[&p0         string ajax_target = Request.Form["ajax_target"];
m2H#G;Zn d{ I0         if (string.IsNullOrEmpty(ajax_target)) return;ITPUB个人空间JD}.w1?#wp$y

N-Li;R6U+f!q t[0         Control target = FindControl(ajax_target);ITPUB个人空间 v@,\q'j4]B
        if (target == null) return;
/lYitCk0 ITPUB个人空间`*\0N~VI
        MethodInfo method = target.GetType().GetMethod("IAjax");
uTm|^$F%@0         if (method == null) return;
mb|+V{0 ITPUB个人空间{ew8k~:I
        Response.Cache.SetNoStore();
/et.y7H!i:K8zs/Y:g0
,o1E,O(T4E1L Vl|0         Response.Write("(");
fjo t6kfa0         method.Invoke(target, null);ITPUB个人空间8^7Z+Z#fCQ)N7EM8v
        Response.Write(")");
vP hM"}U.cJ[[0         Response.End();ITPUB个人空间 gMn1kOJ]R)A
    }
gP%Qa9m-d!lm|5{(Z0     #endregionITPUB个人空间 k l4Y|vmaR[ A\)z
}
vZ9b'd)C @Z!pR }0 ITPUB个人空间q??i!M%v `V
public class Ajax {
6tPM2f,r(e;oX f"B0     public static string Register(Control control, string function, string argument) {
8H#~o?(f5RFC0         if (control == null) return "//This control can not be NULL.";
1l!N'B q D~k w9jE0         return string.Format("ajax({0},'{1}','ajax_target={2}{3},'post','{4}');", function, HttpContext.Current.Request.Url.PathAndQuery,ITPUB个人空间nJ~C Ux
            HttpContext.Current.Server.UrlEncode(control.UniqueID), string.IsNullOrEmpty(argument) ? "'" : "&'+" + argument,
({8xjbS&g0qa0             HttpContext.Current.Response.Charset);
"oX`u,r7ke;s0     }ITPUB个人空间] e'lT!}b-U2c
}
e3i|~1cO0
L6~%AO*OP2rq7q'M0 我在 Page.OnLoad 前处理 ajax,通过 Request.Form["ajax_target"] 得到将要调用的目标,然后反射到目标的 IAjax 这个名字的函数(这里命名有问题,我随便命的),最后通过反射调用它并 Response.EndITPUB个人空间$FcX2E.Fb
Ajax.Register 是注册一个 Ajax,和 ICallBackEventHandler 的使用方法一样,但不同的是现在不需要依赖 webform 和 asp.net 自带的 js库。它依赖传统的 ajax.js 库,并且通用 POST 自己传入参数
6Q| W,AB9r/]5A0 我没有写 ClientScript.RegisterClientScriptBlock 页面自动包含 ajax.js,有兴趣的可以自己改,到时你会遇到 ClientScript.RegisterClientScriptBlock 也依赖 webform,哈哈。。。你需要重新实现相应方法才可以,有兴趣可以直接询问我。ITPUB个人空间~6v#x7[!]
ITPUB个人空间_4l(o\Nt:pFk
使用方法:abc.ascx
(l4e)N+}&^2y P+y0 <%@ Control Language="C#" ClassName="abc" %>
0J^1|vqZwe/T'Sr0 <script runat="server">ITPUB个人空间6f5U|P#KK%Ii#\
    public void IAjax() {
pQB3L&d9cs$R0         int country_id;
-n&N)V.A pPsB"U&Z9q0         int.TryParse(Request.Form["country_id"], out country_id);ITPUB个人空间4cb1PKn4T`
        
*V"j,I~-SV!\^0         Response.Write("[");ITPUB个人空间"T8^ M{#G!L]I;K
        List<CityInfo> citys = City.GetItemsByCountry_id(country_id);ITPUB个人空间Dz?te9P6TFf3Z
        foreach (CityInfo city in citys) {
&kW6uE%}5z0             Response.Write(string.Format("['{0}',{1},'{2}'],", city.Code, city.Id, city.Name); //这里我没有处理 js 问题,你自己处理
5d'I&I d$G0         }
"A/m\M!Aj*a0         Response.Write("]");ITPUB个人空间U'CF_7F1N:yE
    }ITPUB个人空间;\K b]f&{ |]5gs
</script>ITPUB个人空间)x3m)Y'e7s~A/E

F+v!O8D+\})?g*v0 <input type="text" id="country_id">
-T5cd,dt{O0 <input type="button" value="GO" onclick="getCitys()">ITPUB个人空间O^*O#d/`-cCh
<script type="text/javascript">
l4[f`D'r-jf0 function getCitys() {ITPUB个人空间A r*O X;[$c @W
    var receive = function(rt) {
New"Hn2Z-w(B"@Q0         alert(rt);ITPUB个人空间 ]$])@uOw(R.s
    };ITPUB个人空间g x n8}.y7j [
    var args = 'country_id=' + $('country_id').value;
H'Z3h)U h!}g ]0     <%= Ajax.Register(this, "receive", "args") %>ITPUB个人空间'f,q!PgY xN
}
i!W5I3x'os;P-H8i+~0 </script>ITPUB个人空间V(A:L \ FS)M

/c/JT;Q2~ K H/E4F.eQM0
-F)q$D.@[7^:v3s's?0 这样一来,我们就轻松的将 ajax 部署到 UserControl/Page 中,不再依赖 asp.net 的不太好的东西。

TAG:

cnhzlt的个人空间 cnhzlt 发布于2008-05-01 20:31:32
终极?
susanz发布于2008-05-01 20:46:08
test
我来说两句

(可选)

日历

« 2008-10-11  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 12302
  • 日志数: 119
  • 建立时间: 2008-02-08
  • 更新时间: 2008-10-01

RSS订阅

Open Toolbar