使用过.net中的局部刷新功能兄弟都知道,据我的认识,最用的是微软自己提供的和第三方提供组件.微软的提供的方法有两种,一种是VS2005提供的UpdatePanel组件,把updatepanel拖进页面,然后要进行局部刷新的内容(如gridview),只要在updatepanel这个容器里的控件都可以做到局部刷新;第二种方法是VS2003中就有的,即让页面的后代码类实现ICallbackEventHandler接口,该接口有两个方法,RaiseCallbackEvent方法用于客户端处理传过来请求,其中参数是客户端传过来的(JS),GetCallbackResult(没有参数)用于服务器端返回给客户端的结果(text或XML),另外在Page_Load还必须向客户端注册向调用服务器端的脚本,客户端调用这个脚本中函数得到响应数据,具体的细节在这里就多讲了.第三方组件,我知道Ajaxpro,偶没用过.另外,不管是微软提供的还是第三方的方法,我注意到,在运行时向页面注册一些资源文件(js),即一些函数.当然单独注册在页面的也有.
在使用微软的方法实现局部刷新时,我发现一个问题,如果一个页面加载的数据量(2000条记录)很大时,我要刷新的局部数据量很少,只有数据库中的一条记录.异步刷新的速度很慢,和页面加载的数据量成正比,即页面数据量越大,本身整个页面加载的时间就越慢,而局部刷新也会越慢.这不是我们要的局部刷新吧.
仔细看了ajax组件生成的资源文件,仔细看了下代码,大概地了解了,当页面做异步请求时(通过XMLHttpRequest对象),它把请求对象指向了本身即,请求的url是页面中Form的action的值,而Post对参数呢,应该是form里所有的表单字段,所以post的数据量就该不会少,另外,在服务器执行的时候,页面要模拟正常情况执行一遍(这里包括PageLoad方法),然后把再响应的数据丢给XMLHttpRequest,我有一点不明白的是,微软的这种异步请求,是把部分数据还是所有数据丢给XMLHttpRequest对象呢,还有就是在客户端怎么处理返回的数据.
我有一点可以肯定的,页面把正常时操作的流程全走了一遍,如果页面数据量大的话,则会把这些数据再读一遍.而这也许是我们所不需要的.
讲了这么多,看看我的方法,有点老土,用原始的ajax操作来完成.
基本的原理:在客户端,建立XMLHttpRequest对象,请求的对象也是页面本身.传的参数是请求用到的参数,应该很少吧,其中包括一个ajax请求的标识符;建立两个函数于,用于执行请求成功和失败后的操作.在服务器端,需要在两个地方进行操作,一个是Page_Load方法,一个是页面被重写了的OnPreRender方法.前者是在判断有ajax请求的参数时,立即返回,不执行pageload包括的其它代码,OnPreRender用于输出,即返回给XMLHttpRequest的字符串.
具体我将用代码做解释,如下:
客户端用到的代码:
1.Ajax请求函数:
1
//建XMLHttpRequest对象,适应于firefox,ie2
if(typeof XMLHttpRequest=="undefined" && window.ActiveXObject)3
{4
function XMLHttpRequest()5
{6
var arrSign=["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];7
for (var i=0;i<arrSign.length;i++)8
{9
try{10
var oRequest=new ActiveXObject(arrSign[i]);11
return oRequest;12
}13
catch(oError)14
{}15
}16
throw new Error("MSXML is not installed");17
}18
}19
//Complete是请求时执行的函数,fail是失败时执行20
function request(url,Param,Complete,fail,Method,isAsnc)21
{ 22
var oRequest=new XMLHttpRequest(); 23
if(!Method) Method="post"; 24
if(!isAsnc) isAsnc=false;25
oRequest.open(Method,url,isAsnc);26
oRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); 27
oRequest.onreadystatechange=function()28
{29
if(oRequest.readyState==4)30
{31
//alert(oRequest.ResponseText);32
if(oRequest.status==200)33
{34
35
if(typeof(Complete)=="function") 36
{37
Complete(oRequest); 38
}39
}40
else41
if(typeof(fail)=="function") fail(oRequest);42
} 43
44
}//45
oRequest.send(Param); 46
}2.以下是前台页面的用到函数.
1
<script type="text/javascript" language=javascript src="js/include.js"></script>2
<script type="text/javascript" language=javascript>3
if(typeof($)!="function")4
{ 5
function $(id)6
{7
return document.getElementById(id); 8
}9
}10
//fpDetail 是页面中一个div的id,页面中某个地方将调用cc()这个方法11
function cc(para)12
{13
var pars="callback=1¶="+para;14
request($("<%=form1.ClientID%>").action,pars,showResponse,showAlert,null,true);15
return false;16
}17
function showResponse(originalRequest)18
{ 19
$("fpDetail").innerHTML=originalRequest.responseText; 20
}21
function showAlert(request)22
{23
alert("Some Error appear!\r\n"+request.statusText);24
}25
</script>3.后代码文件,主要包括page_load里的操作和OnPreRender里的操作.
1
protected void Page_Load(object sender, EventArgs e)2
{3
string callBack;4
callBack = Request.Form["callback"];5
if (callBack != null && callBack == "1")6
{7
return;8
}9
Button1.Attributes.Add("onclick", "return cc();");10
.11
.12
.13
.14
.//其它操作15
}1
protected override void OnPreRender(EventArgs e)2
{3
//gv1是一个GridView对象4
string callBack;5
callBack=Request.Form["callback"];6
if (callBack != null && callBack == "1")7
{8
Response.Clear();9
//GYF.ExecuteQuery返回一个Datatable10
gv1.DataSource = GYF.ExecuteQuery("sql语句");11
gv1.DataBind();12
StringBuilder sb = new StringBuilder();13
gv1.RenderControl(new HtmlTextWriter(new StringWriter(sb))); 14
Response.Write(sb.ToString());15
Response.End();16
}17
else18
base.OnPreRender(e);19
} 最后,需要注意的是,.net在ajax请求时会验证服务器端控件,如Gridview导出excel时,ajax这种请求可能使得一些服务器控件没有在前端呈现,以致于通不过页面验证,这里可以做如下修正:
1.前端页面中<%page%>中加入 EnableEventValidation=False;
2.重写页面的方法VerifyRenderingInServerForm方法
public override void VerifyRenderingInServerForm(Control control)
{
//什么都不做.
}
好了,总算完了,写了好久啊.
希望大家发表下看法.
浙公网安备 33010602011771号