ASP NET WebForm也可以这样用Ajax.docx
- 文档编号:24545380
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:19
- 大小:39.78KB
ASP NET WebForm也可以这样用Ajax.docx
《ASP NET WebForm也可以这样用Ajax.docx》由会员分享,可在线阅读,更多相关《ASP NET WebForm也可以这样用Ajax.docx(19页珍藏版)》请在冰豆网上搜索。
ASPNETWebForm也可以这样用Ajax
ASP.NETWebForm也可以这样用Ajax
对于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管线和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页面中创建一个被调用的测试方法:
1.public List
2. {
3. return new List
4. }
4. 在Default.aspx中写一个Ajax请求
1.PowerAjax.AsyncAjax(‘TestAjaxMethod’, [1, 2, "333","sss"], function (SucceessResponse) {
2. // 成功后的代码
3.});
PowerAjax.js是用Jquery专门为这个框架封装的一个及其简单的JS类库,这个类库中有两个主要的方法:
PowerAjax.AsyncAjax和PowerAjax.SyncAjax,一个提供同步操作,一个提供异步操作,参数有三个:
第一个参数是即将操作在aspx.cs的Ajax方法的名字(用名字反射方法)。
第二个参数是一个以数组形式组成参数列表数据。
第三个参数是操作成功之后执行执行的回调方法,与c#中的委托一个道理。
以下为这个简单JS库的代码:
1.var PowerAjax = function () { }
2.PowerAjax.__Private = function () { }
3.
4.// 进行异步操作
5.PowerAjax.AsyncAjax = function (methodName, paramArray, success) {
6. PowerAjax.__Private.Ajax(methodName, paramArray, success, true);
7.}
8.
9.// 进行的是同步操作
10.PowerAjax.SyncAjax = function (methodName, paramArray, success) {
11. PowerAjax.__Private.Ajax(methodName, paramArray, success, false);
12.}
13.
14.PowerAjax.__Private.Ajax = function (methodName, paramArray, success, isAsync) {
15. var data = {};
16. switch (paramArray.length) {
17. case 0:
18. data = { 'isAjaxRequest':
true, 'MethodName':
methodName };
19. break;
20. case 1:
21. data = { 'isAjaxRequest':
true, 'MethodName':
methodName, "param0":
paramArray[0] };
22. break;
23. case 2:
24. data = { 'isAjaxRequest':
true, 'MethodName':
methodName, "param0":
paramArray[0], "param1":
paramArray[1] };
25. break;
26. case 3:
27. data = { 'isAjaxRequest':
true, 'MethodName':
methodName, "param0":
paramArray[0], "param1":
paramArray[1], "param2":
paramArray[2] };
28. break;
29. case 4:
30. data = { 'isAjaxRequest':
true, 'MethodName':
methodName, "param0":
paramArray[0], "param1":
paramArray[1], "param2":
paramArray[2], "param3":
paramArray[3] };
31. break;
32. case 5:
33. data = { 'isAjaxRequest':
true, 'MethodName':
methodName, "param0":
paramArray[0], "param1":
paramArray[1], "param2":
paramArray[2], "param3":
paramArray[3], "param4":
paramArray[4] };
34. break;
35. }
36.
37. var url = document.location.href;
38. $.ajax({
39. type:
"post",
40. url:
url,
41. data:
data,
42. async:
isAsync,
43. datatype:
"json",
44. contentType:
"application/x-www-form-urlencoded; charset=UTF-8",
45. success:
function (response) {
46. success(response);
47. },
48. error:
function (response) {
49. if (response.status == 500) {
50. var errorMessage = response.responseText;
51. var errorTitle = errorMessage.substring(errorMessage.indexOf("
52. throw new Error("服务器内部错误:
" + errorTitle);
53. }
54. }
55. });
56.}
5. 更改Default.aspx.cs的继承页面为AjaxBasePage
1.public partial class _Default :
AjaxBasePage
6. 主要基类:
AjaxBasePage类
如下代码:
1.public class AjaxBasePage :
System.Web.UI.Page
2.{
3. ///
4. /// 是否是一个ajax请求。
5. ///
6. public bool IsAjaxRequest { get; private set; }
7.
8. ///
9. /// 如果是Ajax请求,劫持页面生命周期的PreInit的事件,直接返回Response
10. ///
11. protected override void OnPreInit(EventArgs e)
12. {
13. AjaxRequest ajaxRequest = AjaxRequest.GetInstance(Request.Form);
14. this.IsAjaxRequest = ajaxRequest.IsAjaxRequest;
15.
16. if (this.IsAjaxRequest)
17. {
18. AjaxApplication ajaxApplication = new AjaxApplication(this, ajaxRequest);
19. ajaxApplication.EndRequest();
20. }
21. else
22. {
23. // 如果不是Ajax请求,继续执行页面生命周期的剩余事件
24. base.OnPreInit(e);
25. }
26. }
27.}
该类重写了PreInit方法,判断请求是否是一个Ajax请求。
通过AjaxRequest类接收并处理接收到的请求,提取出一些有效的数据,比如说是否是一个Ajax请求,方法的名字,参数列表(AjaxParameter类)。
至于AjaxParameter类,内部用的数据结构其实是一个字典,并使用索引来提供对数据的方便访问,提供一个Count属性,方便获取参数的个数。
如下代码
1.public class AjaxParameter
2. {
3. private IDictionary
4.
5. ///
6. /// 返回参数的个数。
7. ///
8. public int Count
9. {
10. get
11. {
12. return this.m_DictionaryParamsData.Count;
13. }
14. }
15.
16. ///
17. /// 索引具体参数的值。
18. ///
19. ///
20. ///
21. public string this[int index]
22. {
23. get
24. {
25. if (index >= 5 || index < 0)
26. {
27. throw new NotSupportedException("请求方法的参数的个数限制为:
0-5");
28. }
29. return this.m_DictionaryParamsData[index];
30. }
31. }
32.
33. public AjaxParameter(IDictionary
34. {
35. this.m_DictionaryParamsData = paramsData;
36. }
37. }
AjaxRequest类的设计思路其实是模仿HttpContext设计,HttpContext能够从基础的http请求报文分析出以后处理将要用到的数据(response,request,session,cookie等等)数据,而AjaxRequest通过分析Ajax的Post请求的数据域Data分析出各种以后会用到的数据。
如下是该类的代码:
1.public class AjaxRequest
2. {
3. private Dictionary
4. private AjaxParameter m_AjaxParameter;
5. private int m_Count = 0;
6.
7. #region 属性
8. ///
9. /// 是否是一个Ajax请求。
10. ///
11. public bool IsAjaxRequest { get; private set; }
12.
13. ///
14. /// 请求的方法名字。
15. ///
16. public string MethodName { get; private set; }
17.
18. ///
19. /// 参数数据。
20. ///
21. public AjaxParameter Parameters
22. {
23. get { return this.m_AjaxParameter; }
24. }
25. #endregion
26.
27. #region 构造函数
28. private AjaxRequest(NameValueCollection nameValueCollection)
29. {
30. this.IsAjaxRequest = nameValueCollection["isAjaxRequest"] == "true";
31. if (this.IsAjaxRequest)
32. {
33. this.MethodName = nameValueCollection["MethodName"];
34.
35. foreach (string value in nameValueCollection)
36. {
37. string formKey = string.Format("param{0}", this.m_Count);
38. if (nameValueCollection[formKey] !
= null)
39. {
40. this.m_DictionaryParamsData.Add(this.m_Count, nameValueCollection[formKey]);
41. this.m_Count++;
42. }
43. }
44. m_AjaxParameter = new AjaxParameter(this.m_DictionaryParamsData);
45. }
46. }
47.
48. #endregion
49.
50. #region 实例方法
51. public static AjaxRequest GetInstance(NameValueCollection nameValueCollection)
52. {
53. return new AjaxRequest(nameValueCollection);
54. }
55. #endregion
56.
57. #region ToString
58. public override string ToString()
59. {
60. return this.MethodName;
61. }
62. #endregion
63. }
通过分析AjaxRequest的属性IsAjaxRequest可判断是否为Ajax请求,若该请求为一个Ajax请求,那么创建一个AjaxApplication实例,在创建AjaxApplication实例的过程中会利用当前页面和AjaxRequest提供的数据进行实际方法的调用(反射),该类是执行Ajax方法的核心类,其中会判断是否读取的到的方法是一个有效的方法,并判断从JS中AjaxApplication传入的参数类型的有效性,目前只提供对以下13中参数提供支持,如下:
1.(String、Boolean、Int32、Int64、UInt32、UInt64、Single、Double、Decimal、DateTime、DateTimeOffset、TimeSpan、Guid)
如果方法中出现非以上类型,将会抛出异常。
为了方便Ajax的调试,在JS前段类库中我会对异常进行处理,并抛出Error,Error信息有效的截取了继承自Exception的抛出信息,至于如何获 得更加详细的JS调试信息,以后JS库中可能会做提供更加详细的调用信息,毕竟框架是在改进中进行的。
如下是AjaxApplication类的具体代码:
1.public class AjaxApplication
2. {
3. private AjaxBasePage m_AjaxBasePage;
4. private object m_ResponseData;
5.
6. public AjaxApplication(AjaxBasePage ajaxBasePage, AjaxRequest ajaxRequest)
7. {
8. this.m_AjaxBasePage = ajaxBasePage;
9.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ASP NET WebForm也可以这样用Ajax WebForm 可以 这样 Ajax