在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
对于asp.net WebForm项目,进行Ajax操作大概有三种方式:web服务(.asmx文件) , 一般处理程序(.ashx)和 一些Ajax控件。 对于.net提供的ajax控件,暂且不说,只说另外两种方式,都需要引入额外的代码文件对Ajax进行操作(asmx和ashx,且web服务还要引入一个cs文件与之对应),假如要对Example.aspx这个页面添加一些自定义的Ajax操作,并且这些Ajax操作并不会在别的页面上用到,如此不得不引入额外的代码文件完成这个操作,假如这个Ajax操作很简单,只需要一个简单的函数就可以执行,那岂不是很麻烦的过程吗?如此一来,随着项目中Ajax操作的增多,ashx和asmx文件都会随着时间的增长而增长,项目的维护也会随之加倍。为什么我们不能把Ajax操作的后台代码直接放在Example.aspx对应的Example.aspx.cs文件里 ? 如果能这样做,以上两种烦恼都会迎刃而解,不是吗? 于是,按照以上思路,实现了如下Ajax框架。先来看这个框架的实现机制:
上图是自己画的一个缩减版IIS接收到一个aspx请求的HttpApplication管线和asp.net Page在执行ProcessRequest()方法中的页面生命周期的部分事件。Page本身是继承自IHttpHandler接口,IHttpHandler提供了一个重要的约束方法ProcessRequest,该方法是对接收到的信息(HttpContext)进行具体的处理同样,一般处理程序和web服务也实现了自己的IHttpHandler,并以此提供一些Ajax服务。具体的操作过程请自行查找MSDN。 原理是在页面生命周期开始的第一个事件PreInit进行一些处理,一旦发现劫持到的请求是一个ajax请求,那么利用C#的反射来调用aspx.cs中定义的方法,执行完方法之后,调用Response.End()方法,调用这个方法会直接跳到管线的EndRequest事件,从而结束请求,这样就无需走一些没有必要的页面生命周期的步骤,从而完成一个Ajax操作。如果发现是一个正常的操作,那么就走正常流程。
下面以一个简单例子说明该Ajax框架的使用: 1. 添加一个解决方案 2. 新建一个 Default.aspx 页面 3. 在Default.aspx.cs页面中创建一个被调用的测试方法: public List<string> TestAjaxMethod(int a, string b, float c) { return new List<string> { a.ToString(), b, c.ToString() }; } 4. 在Default.aspx中写一个Ajax请求 PowerAjax.AsyncAjax(‘TestAjaxMethod’, [1, 2, "333","sss"], function (SucceessResponse) { // 成功后的代码 }); PowerAjax.js是用Jquery专门为这个框架封装的一个及其简单的JS类库,这个类库中有两个主要的方法:PowerAjax.AsyncAjax和PowerAjax.SyncAjax,一个提供同步操作,一个 提供异步操作,参数有三个: 第一个参数是即将操作在aspx.cs的Ajax方法的名字(用名字反射方法)。 第二个参数是一个以数组形式组成参数列表数据。 第三个参数是操作成功之后执行执行的回调方法,与c#中的委托一个道理。 以下为这个简单JS库的代码:
5. 更改Default.aspx.cs的继承页面为AjaxBasePage public partial class _Default : AjaxBasePage 6. 主要基类:AjaxBasePage类 如下代码: public class AjaxBasePage : System.Web.UI.Page { /// <summary> /// 是否是一个ajax请求。 /// </summary> public bool IsAjaxRequest { get; private set; } /// <summary> /// 如果是Ajax请求,劫持页面生命周期的PreInit的事件,直接返回Response /// </summary> protected override void OnPreInit(EventArgs e) { AjaxRequest ajaxRequest = AjaxRequest.GetInstance(Request.Form); this.IsAjaxRequest = ajaxRequest.IsAjaxRequest; if (this.IsAjaxRequest) { AjaxApplication ajaxApplication = new AjaxApplication(this, ajaxRequest); ajaxApplication.EndRequest(); } else { // 如果不是Ajax请求,继续执行页面生命周期的剩余事件 base.OnPreInit(e); } } }
该类重写了PreInit方法,判断请求是否是一个Ajax请求。通过AjaxRequest类接收并处理接收到的请求,提取出一些有效的数据,比如说是否是一个Ajax请求,方法的名字,参数列表(AjaxParameter类)。 至于AjaxParameter类,内部用的数据结构其实是一个字典,并使用索引来提供对数据的方便访问,提供一个Count属性,方便获取参数的个数。 如下代码:
AjaxRequest类的设计思路其实是模仿HttpContext设计,HttpContext能够从基础的http请求报文分析出以后处理将要用到的数据(response,request,session,cookie等等)数据,而AjaxRequest通过分析Ajax的Post请求的数据域Data分析出各种以后会用到的数据。如下是该类的代码:
通过分析AjaxRequest的属性IsAjaxRequest可判断是否为Ajax请求,若该请求为一个Ajax请求,那么创建一个AjaxApplication实例,在创建AjaxApplication实例的过程中会利用当前页面和AjaxRequest提供的数据进行实际方法的调用(反射),该类是执行Ajax方法的核心类,其中会判断是否读取的到的方法是一个有效的方法,并判断从JS中AjaxApplication传入的参数类型的有效性,目前只提供对以下13中参数提供支持,如下:
如果方法中出现非以上类型,将会抛出异常。为了方便Ajax的调试,在JS前段类库中我会对异常进行处理,并抛出Error,Error信息有效的截取了继承自Exception的抛出信息,至于如何获 得更加详细的JS调试信息,以后JS库中可能会做提供更加详细的调用信息,毕竟框架是在改进中进行的。如下是AjaxApplication类的具体代码:
全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论