AjaxHandlerFactory实现了IHandlerFactory接口,用来根据请求生成具体的Handler,它需要在web.config进行注册使用。AjaxHandlerFactory的GetHandler是我们拦截请求的第一步。通过请求头的AjaxFlag:XHR来判断是否需要我们处理,如果是,则创建一个Handler,否则按照普通的方式进行。由于我们的方法是写在.aspx.cs内的,我们的请求是.aspx后缀的,也就是页面(Page,实现了IHttpHandler)类型,Page是通过PageHandlerFactory创建的,PageHandlerFactory也实现了IHandlerFactory接口,表示它是用来创建处理程序的。所以我们需要用PageHandlerFactory来创建一个IHttpHandler,不过PageHandlerFactory的构造函数是protected internal类型的,我们无法直接new一个,所以需要通过一个CommonPageHandlerFactory继承它来实现。
通过PageHandlerFactory获得Page后,结合方法名称,我们就可以反射获取AjaxMethodAttribute标记属性了。然后根据它的相关属性生成具体的Handler。具体代码如下:
internal class CommonPageHandlerFactory : PageHandlerFactory { }
internal class AjaxHandlerFactory : IHttpHandlerFactory
{
public void ReleaseHandler(IHttpHandler handler)
{
}
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
HttpRequest request = context.Request;
if (string.Compare(request.Headers[AjaxConfig.Key], AjaxConfig.Value, true) == 0)
{
//检查函数标记
string methodName = request.Headers[AjaxConfig.MethodName];
if (methodName.IsNullOrEmpty())
{
Executor.EndCurrentRequest(context, "方法名称未正确指定!");
return null;
}
try
{
CommonPageHandlerFactory ajaxPageHandler = new CommonPageHandlerFactory();
IHttpHandler handler = ajaxPageHandler.GetHandler(context, requestType, url, pathTranslated);
Page page = handler as Page;
if (page == null)
{
Executor.EndCurrentRequest(context, "处理程序类型必须是aspx页面!");
return null;
}
return GetHandler(page, methodName, context);
}
catch
{
Executor.EndCurrentRequest(context, url + " 不存在!");
return null;
}
}
if (url.EndsWith(".aspx", StringComparison.CurrentCultureIgnoreCase))
{
CommonPageHandlerFactory orgPageHandler = new CommonPageHandlerFactory();
return orgPageHandler.GetHandler(context, requestType, url, pathTranslated);
}
return null;
}
/// <summary>
/// 获取自定义处理程序
/// </summary>
/// <param name="page">处理页面</param>
/// <param name="methodName">处理方法</param>
/// <param name="context">当前请求</param>
private IHttpHandler GetHandler(Page page, string methodName, HttpContext context)
{
//根据Page和MethodName进行反射,获取标记属性(下面详细介绍)
CacheMethodInfo methodInfo = Executor.GetDelegateInfo(page, methodName);
if (methodInfo == null)
{
Executor.EndCurrentRequest(context, "找不到指定的Ajax方法!");
return null;
}
AjaxMethodAttribute attribute = methodInfo.AjaxMethodAttribute;
if (attribute.ServerCache > 0)
{
//先查找缓存
object data = CacheHelper.TryGetCache(context);
if (data != null)
{
Executor.EndCurrentRequest(context, data);
return null;
}
}
if (attribute.IsAsync)
{
//异步处理程序
return ASyncAjaxHandler.CreateHandler(page, methodInfo, attribute.SessionState);
}
return SyncAjaxHandler.CreateHandler(page, methodInfo, attribute.SessionState);
}
}









