本文内容
-
概述
-
Ext.Net.ResourceHandler 资源处理程序
-
参考资料
概述
页面依赖 Ext.Net. ResourceManager 控件初始化其资源,将 CSS 和脚本的引用和内容加入到页面。
若在页面引用 Ext.Net. ResourceManager 控件,如下所示:
那么,页面呈现的内容如下所示:
1:
2:
1:
2:
1:
2:
1:
2:
3: //
4: Ext.net.ResourceMgr.init({id:"ResourceManager1",BLANK_IMAGE_URL:"/extjs/resources/images/default/s-gif/ext.axd",aspForm:"form1",theme:"blue"});Ext.onReady(function(){Ext.QuickTips.init();});
5: //]]>
6:</ script >
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12: //
13: var theForm = document.forms['form1'];
14: if (!theForm) {
15: theForm = document.form1;
16: }
17: function __doPostBack(eventTarget, eventArgument) {
18: if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
19: theForm.__EVENTTARGET.value = eventTarget;
20: theForm.__EVENTARGUMENT.value = eventArgument;
21: theForm.submit();
22: }
23: }
24: //]]></ script >
可以看到,页面头增加了几个资源引用和资源内容。这些资源都是 Ext.Net 的嵌入资源。但这些对于一个 Ajax 框架远远不够,仅仅是个开始。当用户再次请求资源时,如何处理这些资源?下面主要说明 Ext.Net.ResourceHanlder 如何管理自己的内嵌资源。
Ext.Net.ResourceHandler 资源管理程序
Web.config 文件
先看下使用 Ext.Net 时,对 Web.config 文件的配置。如下所示:
The following system.web section is only requited for running ASP.NET AJAX under Internet
Information Services 6.0 (or earlier). This section is not necessary for IIS 7.0 or later.
-->
The system.webServer section is required for running ASP.NET AJAX under Internet Information Services 7.0.
It is not necessary for previous version of IIS.
-->
name="DirectRequestModule"
preCondition="managedHandler"
type="Ext.Net.DirectRequestModule, Ext.Net"
/>
name="DirectRequestHandler"
verb="*"
path="*/ext.axd"
preCondition="integratedMode"
type="Ext.Net.ResourceHandler"
/>
其中,
- <add path="*/ext.axd" verb="*" type="Ext.Net.ResourceHandler" validate="false" /> 是任何包含 "*/ext.axd" 的 HTTP 请求,都会调用 Ext.Net.ResourceHandler 处理程序。
- <add name="DirectRequestModule" type="Ext.Net.DirectRequestModule, Ext.Net" /> 是在每次发出 HTTP 请求时,都会调 Ext.Net.DirectRequestModule 处理模块。该模块作为 ASP.NET 请求管道的一部分调用,在整个请求过程中访问生命周期事件。该模块使你可以检查传入和传出的请求并根据该请求进行操作。
Ext.Net.ResourceHandler 资源处理程序
Ext.Net.ResourceHandler 资源处理程序位于 Ext.Net 的 Core 目录。该处理程序处理任何包含 "*/ext.axd" 的 HTTP 请求。注意,它处理的单个请求。也就是说,对于页面头中的每项包含 "*/ext.axd" 的资源都会调用该处理程序,如
<script type="text/javascript" src="/extjs/adapter/ext/ext-base-js/ext.axd?v=17083"></script> 和
<script type="text/javascript" src="/extjs/ext-all-js/ext.axd?v=17083"></script> 等。其类图如下所示:
我们只需关心该处理程序的 Public 方法。其中 ProcessRequest 方法最重要。代码如下:
public override void ProcessRequest(HttpContext context)
{
this.context = context;
string file = this.context.Request.RawUrl;
bool isInitScript = file.Contains("extnet/extnet-init-js/ext.axd?");
if (!ResourceHandler.IsSourceModified(context.Request) && !isInitScript)
{
context.Response.SuppressContent = true;
context.Response.StatusCode = 304;
context.Response.StatusDescription = "Not Modified";
context.Response.AddHeader("Content-Length", "0");
return;
}
this.SetResponseCache(context);
if (isInitScript)
{
string key = file.RightOfRightmostOf('?');
if (key.IsNotEmpty())
{
try
{
string script = this.context.Session[key].ToString();
this.context.Session.Remove(key);
CompressionUtils.GZipAndSend(script);
}
catch (NullReferenceException)
{
throw new InitializationScriptNotFoundException("The Ext.NET initialization script was not found.");
}
}
}
else
{
try
{
this.sm = new ResourceManager();
this.compress = CompressionUtils.IsGZipSupported && this.sm.GZip;
this.SetWebResourceName(file);
this.stream = this.GetType().Assembly.GetManifestResourceStream(this.webResource);
string ext = this.webResource.RightOfRightmostOf('.');
this.compress = this.compress && !this.IsImage(ext);
switch (ext)
{
case "js":
this.WriteFile("text/javascript");
break;
case "css":
this.WriteFile("text/css");
break;
case "gif":
this.WriteImage("image/gif");
break;
case "png":
this.WriteImage("image/png");
break;
case "jpg":
case "jpeg":
this.WriteImage("image/jpg");
break;
}
}
catch (Exception e)
{
string s = this.IsDebugging ? e.ToString() : e.Message;
context.Response.StatusDescription = s.Substring(0, Math.Min(s.Length, 512));
this.context.Response.Redirect(Page.ClientScript.GetWebResourceUrl(this.sm.GetType(), this.webResource));
}
finally
{
if (this.stream != null)
{
this.stream.Close();
}
}
}
}
当用户初次请求页面时,该处理程序还不会执行。因为,那时页面关于嵌入资源(包括 CSS 和脚本)才刚刚添加。可当用户再次请求该页面时,对所有的嵌入资源就会调用这个处理程序。该方法的伪代码如下:
public override void ProcessRequest(HttpContext context)
{
if (若该资源为 “extnet-init.js”,且该资源未改动)
{
// 因为,作为嵌入在程序集的资源 !ResourceHandler.IsSourceModified 肯定为false。
// 则响应客户端HTTPCODE 为304——Not Modified,并返回。
}
// 设置该资源的缓存信息
if (若该资源为 “extnet-init.js”)
{
// 则从当前 HTTP 请求的回话中删除,并以压缩方式发送给客户端。
}
else
{
// 判断是否支持压缩 GZIP
// 从程序集获得嵌入资源,并以“压缩”方式发送 CSS 和脚本文件,以“非压缩”方式发送图像给客户端
}
}
参考资料
MSDN HTTP 处理程序和 HTTP 模块概述
利用 IHttpHandler 自定义 HTTP 处理程序
.NET Framework IHttpHandler
IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述