Ext.Net 1.2.0_分析 Ext.Net.ResourceHandler 资源处理程序

本文内容

  • 概述

  • Ext.Net.ResourceHandler 资源处理程序

  • 参考资料

概述

页面依赖 Ext.Net. ResourceManager 控件初始化其资源,将 CSS 和脚本的引用和内容加入到页面。

若在页面引用 Ext.Net. ResourceManager 控件,如下所示:

Ext.Net. ResourceManager 控件

那么,页面呈现的内容如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <link rel="stylesheet" type="text/css" href="/extjs/resources/css/ext-all-embedded-css/ext.axd?v=17083" />
<title>
 
</title>
    <script type="text/javascript" src="/extjs/adapter/ext/ext-base-js/ext.axd?v=17083"></script>
   1:  
   2:     <script type="text/javascript" src="/extjs/ext-all-js/ext.axd?v=17083">
   1: </script>
   2:     <script type="text/javascript" src="/extnet/extnet-core-js/ext.axd?v=17083">
   1: </script>
   2:     <script type="text/javascript" src="/extnet/locale/ext-lang-zh-CN-js/ext.axd?v=17083">
   1: </script>
   2:     <script type="text/javascript">
   3:     //<![CDATA[
   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: </head>
   3: <body>
   4:     <form name="form1" method="post" action="WebForm2.aspx" id="form1">
   5: <div>
   6: <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
   7: <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
   8: <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNTgyMzk4N2QYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFEFJlc291cmNlTWFuYWdlcjFtzMaC7eCHSStptAvkxOouI11aMQ==" />
   9: </div>
  10:  
  11: <script type="text/javascript">
  12: //<![CDATA[
  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>
 
 
<div>
 
    <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLl9M/1DQLk1b+VAvPeIxQnrPccjp0QWBmQuJLa1QHw" />
</div>
    
    </form>
</body>
</html>

可以看到,页面头增加了几个资源引用和资源内容。这些资源都是 Ext.Net 的嵌入资源。但这些对于一个 Ajax 框架远远不够,仅仅是个开始。当用户再次请求资源时,如何处理这些资源?下面主要说明 Ext.Net.ResourceHanlder 如何管理自己的内嵌资源。

Ext.Net.ResourceHandler 资源管理程序

Web.config 文件

先看下使用 Ext.Net 时,对 Web.config 文件的配置。如下所示:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="extnet" type="Ext.Net.GlobalConfig" requirePermission="false" />
    </configSections>
  
    <extnet scriptMode="Release" /> <!-- See Property Options in README.txt -->
  
    <!-- 
        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.
    -->
    <system.web>
        <httpHandlers>
            <add path="*/ext.axd" verb="*" type="Ext.Net.ResourceHandler" validate="false" />
        </httpHandlers>
        <httpModules>
            <add name="DirectRequestModule" type="Ext.Net.DirectRequestModule, Ext.Net" />
        </httpModules>
    </system.web>
  
    <!-- 
        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.
    -->
    <system.webServer>
        <validation validateIntegratedModeConfiguration="false"/>
        <modules>
            <add 
                name="DirectRequestModule" 
                preCondition="managedHandler" 
                type="Ext.Net.DirectRequestModule, Ext.Net" 
                />
        </modules>
        <handlers>
            <add 
                name="DirectRequestHandler" 
                verb="*" 
                path="*/ext.axd" 
                preCondition="integratedMode" 
                type="Ext.Net.ResourceHandler"
                />
        </handlers>
    </system.webServer>
</configuration>

其中,

  • <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> 等。其类图如下所示:

Ext.Net.ResourceHandler 

我们只需关心该处理程序的 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 模块概述 http://msdn.microsoft.com/zh-cn/library/bb398986(v=VS.90).aspx

利用 IHttpHandler 自定义 HTTP 处理程序 http://www.cnblogs.com/liuning8023/archive/2011/11/29/2268445.html

.NET Framework IHttpHandler http://msdn.microsoft.com/zh-cn/library/system.web.ihttphandler(v=VS.90).aspx

IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述 http://msdn.microsoft.com/zh-cn/library/ms178473.aspx

原文地址:https://www.cnblogs.com/liuning8023/p/2296263.html