Ajax框架原理分析之Ext.Net
时间:2010-11-26 来源:永远的阿哲
1.静态的AJAX方法实现.
当把[DirectMethod]标记标在一个静态方法上时,Ext.Net是通过HttpModule来截获Http请求实现的.
在应用程序生命周期的PostAcquireRequestState事件内中加入处理函数
代码 public void Init(HttpApplication app){
app.PostAcquireRequestState += OnPostAcquireRequestState;
app.PreSendRequestHeaders += RedirectPreSendRequestHeaders;
app.ReleaseRequestState += AjaxRequestFilter;
}
如果是AJAX请求且是静态AJAX方法则调用ProcessRequest方法
{
HttpApplication app = (HttpApplication)sender;
HttpRequest request = app.Context.Request;
if (RequestManager.IsAjaxRequest)
{
if (DirectMethod.IsStaticMethodRequest(request) /*|| Utilities.ReflectionUtils.IsTypeOf(app.Context.Handler, "System.Web.Script.Services.ScriptHandlerFactory+HandlerWrapper")*/)
{
this.ProcessRequest(app, request);
}
}
}
通过反射来调用方法,并结束服务器处理过程,将结果返回到客户端(有删节)
代码 // Get handlerHandlerMethods handler = HandlerMethods.GetHandlerMethods(context, request.FilePath);
// Get method name to invoke
string methodName = HandlerMethods.GetMethodName(context);
DirectMethod directMethod = handler.GetStaticMethod(methodName);
object result = directMethod.Invoke();
app.Context.Response.Clear();
app.Context.Response.ClearContent();
app.Context.Response.ClearHeaders();
app.Context.Response.StatusCode = 200;
app.Context.Response.ContentType = "application/json";
app.Context.Response.Charset = "utf-8";
app.Context.Response.Cache.SetNoServerCaching();
app.Context.Response.Cache.SetMaxAge(TimeSpan.Zero);
app.Context.Response.Write(responseObject.ToString());
app.CompleteRequest();
因为是直接通过反射来实现,没有执行页面的生命周期,所以Ext.Net官方推荐此种编写方式.
2.实例的AJAX方法实现.
我们要重点关注ResourceManager类,它是整个AJAX请求的核心
首先我们来看是如何实现AJAX方法的调动.
当客户端发起一个AJAX请求时,Ext.Net会在POST数据中加入以下两个键值对:
__EVENTARGUMENT:btnOK|event|Click
__EVENTVALIDATION:ResourceManager1
表示由ResourceManager类型的ResourceManager1实例来处理这次AJAX请求.具体发起请求的按钮是btnOK,形式为事件,方式为Click.
在ResourceManager类的OnLoad事件中,如果是AJAX请求,则在LoadComplete事件中加入Page_AjaxLoadComplete处理函数
代码 protected override void OnLoad(EventArgs e){
base.OnLoad(e);
if (RequestManager.IsAjaxRequest && !this.Page.IsPostBack && !this.IsDynamic)
{
this.Page.LoadComplete += Page_AjaxLoadComplete;
}
}
在Page_AjaxLoadComplete处理函数中,借用回发的处理方法来实现AJAX调用:
if (_ea.IsNotEmpty())
{
string _et = this.Page.Request["__EVENTTARGET"];
if (_et == this.UniqueID)
{
this.RaisePostBackEvent(_ea);
}
return;
}
在RaisePostBackEvent方法中,实现对具体控件具体方法的具体调用:
代码 string controlID = args[0];string controlEvent = args[2];
ctrl = ControlUtils.FindControlByClientID(this.Page, controlID, true, null);
case AjaxRequestType.Event:
Observable observable = ctrl as Observable;
if (observable == null)
{
if (ctrl is ResourceManagerProxy)
{
((ResourceManagerProxy)ctrl).FireAsyncEvent(controlEvent, extraParams);
}
else if (ctrl is ResourceManager)
{
this.FireAsyncEvent(controlEvent, extraParams);
}
else
{
throw new HttpException("The control with ID '{0}' is not Observable".FormatWith(controlID));
}
}
if (observable != null)
{
observable.FireAsyncEvent(controlEvent, extraParams);
}
break;
然后我们来看Ext.Net是如何将处理结果返回给客户端的.