一个例子小探Ajax.net的使用

最近在用ASP.NET做一个OA的小项目,算是用来练手的,由于项目中遇到不少的需要Ajax的地方,但大部分都可以用UpdatePanel解决,这两天终于遇到一个无法用UpdatePanel解决的了。

 

需求如下:从客户端上传文件,文件名验证之类的自不用提,当上传文件时,首先要判断在服务器对应的目录下是否已存在同名文件或文件夹,如存在,则有如下提示:“您要创建的文件已存在,将自动修改文件名,继续吗?”,若用户选择“是”,则修改文件名,规则类似Windows(文件名后面加(1)、(2)……之类的序号),用此文件名保存上传的文件。

 

我们知道,若先执行C#代码,再执行javascript代码,很容易,执行完C#代码以后使用ClientScript.RegisterStartupScript()就能搞定,若该服务器控件位于UpdatePanel中或者为UpdatePanel更新的触发器时,也只用把ClientScript.RegisterStartupScript()换成ScriptManager.RegisterStartupScript()即可。反过来,先执行javascript代码,再执行C#代码,也只需要分别写按钮的OnClientClick和OnClick事件也可以实现。

 

但是,我们现在的流程却并非这么简单。首先判断文件在服务器中是否存在需要执行C#代码,然后弹出确认框需要执行javascript代码,最后执行改名并将文件上传到服务器上又需要执行C#代码,这个C#-->javascript-->C#的执行顺序,用普通的UpdatePanel显然是无法做到的。

 

于是,我们的主角Ajax.net必须得登场了(假定当前页面为CreateNewFile.aspx和CreateNewFile.aspx.cs,需要Ajax调用的方法IsFileExist()位于CreateNewFile.aspx.cs中)。

 

第一步,在网上下载一个Ajax.dll。

 

第二步,在项目添加对Ajax.dll的引用。

 

第三步,在web.config文件中做如下配置:

 

 

第四步,在页面的Page_Load方法中注册Ajax方法所在的类:Ajax.Utility.RegisterTypeForAjax(typeof(CreateNewFile));

 

第五步,将需要Ajax调用的方法前面加上Attributes,表明这是一个Ajax方法。

 

[Ajax.AjaxMethod] public bool IsFileExist() { }

 

第六步,在javascript中调用具有AjaxMethod特性的C#方法。

 

同步调用:

 

 

异步调用:

 

 

至此,在客户端利用Ajax调用服务器端方法的工作已经完成。

 

目前看起来,似乎一切都很完美,但实际情况却总是给我们惊喜,里面的一些细节问题不少。

 

第一个问题,在AjaxMethod中,无法访问服务器控件。我一开始试图访问本文框txtFileName,获取它的Text,结果调试中每次运行到服务器控件这一行,便直接跳出当前方法(原因我们后面再看)。没办法,我只好将IsFileExist方法中加了一个String类型参数fileName,然后先在客户端获取本文框txtFileName的值(document.getElementById("<%=txtFileName.ClientID %>").value),然后再传值进入这个方法,问题解决。若您想对本文框txtFileName做一些设置,便直接写在客户端的javascript脚本中,因为客户端脚本本来就是用来渲染效果的。AjaxMethod的作用永远是——传入某些必要的数据,处理之后返回你需要的数据。

 

第二个问题,对服务器内置对象的访问。

 

对于Session对象的访问,我们只需要在[Ajax.AjaxMethod]中加入[Ajax.AjaxMethod(HttpSessionStateRequirement.Read)],当然,我们也可以加入无权限(None)或者读写(ReadWrite)权限。

 

对于Request对象的访问,由于内置的Request对象是属于Page对象的,而我们利用Ajax访问服务器端并不是通过页面提交的方式,故直接调用Request对象将会报空引用异常,我们需要通过HttpContext.Current.Request来访问Request对象。但此时问题又来了,我们传通过URL传过来的参数用Request.QueryString居然访问不了,为什么呢?通过调试,我们可以发现,此时的Request对象中的Url属性变成了“/ajax/CreateNewFile,OA.ashx?method=IsFileExist&_session=no”,而当前页面的URL则变成了Request对象的UrlReferrer属性,这也很好理解,我并未提交页面,而是通过XmlHttpRequest发送的请求,自然无法访问Page对象中的属性,这也可以解释第一个问题,为何不能访问服务器控件,因为它们都属于Page对象。

 

那么,如何访问到QueryString呢?我们有的时候的确是需要它,方法只有一种,那便是对URL的解析。当然,这又能分两种,一种是客户端,通过javascript的window.location对象进行解析,将解析后的数据通过参数传给服务器端;另一种是服务器端,通过HttpContext.Current.Request对象的UrlReferrer对象进行解析。个人推荐客户端和服务器端实现难度差不多时,放在客户端解决,因为服务器端可能负载了成千上万人,而客户端却只有一人使用,尽量减少服务器负担。

 

其他的内置对象不讨论,不过貌似Server对象访问很正常。

 

目前使用Ajax.net的心得就这么多,暂属于知其然不知其所以然的地步,后面的还有待进一步探索,但不管怎么样,这练手的东西终究还是发挥了它的功效了的,余愿足矣。

你可能感兴趣的:(C#)