zoukankan      html  css  js  c++  java
  • 利用WebResource.axd通过一个URL来访问装配件的内置资源

    [转载]

    本文英文原版及代码下载:
    http://aspnet.4guysfromrolla.com/articles/080906-1.aspx

    利用WebResource.axd通过一个URL来访问装配件的内置资源

    导言:

    很多ASP.NET server控件都需要另外的外部资源来实现某些功能.比如,使用任何一个ASP.NET validation验证控件时,都需要一系列的JavaScript functions来执行它们的客户端验证.虽然可以在页面上添加这些JavaScript functions,不过更高效的方法是将这些函数封装在一个外部的JavaScript文件里,然后在页面通过<script src="PathToExternalJavaScriptFile" type="text/javascript" >的形式来将该文件包含在页面里.这样一来不仅可以实现对页面的瘦身,还可以允许浏览器对该JavaScript文件施行缓存(这样就不用每个页面在登录/回传时向浏览器发送该JavaScript代码了)

    在ASP.NET 2.0之前,用户浏览器要访问这种外部资源的话,我们必须将它们作为具体的文件放在文件系统里.如果你使用ASP.NET 1.x的验证控件的话,你的页面必须添加一个对JavaScript文件的引用,如/aspnet_client/system_web/version/WebUIValidation.js.这些外部文件有碍最后的部署.

    为解决这个问题,ASP.NET 2.0允许将外部资源植入控件的装配件里,通过一个指定的URL对其访问.将外部images, JavaScript files,CSS files植入控件的装配件后,部署就容易了,因为所有的资源都包含在.dll文件里了. 完成植入操作后,在ASP.NET 2.0页面里我们可以通过一个指定的URL(WebResource.axd)来实现对这些资源的访问.

    本文我们探讨如何将外部资源植入装配件以及如何通过一个指定的URL来对其访问,该技术简化了安装和部署.

    一个Custom Control示例...

    为了考察ASP.NET 2.0里的外部资源特性,我们需要构建一个包含外部资源的自定义控件.就本文而言,我将创建一个很简单的控件来对TextBox控件的基本函数进行扩充.该控件—FunkyTextBox,在其客户端的onkeypress event事件里,用一个color数组里定义的颜色随机的改变TextBox的底色.

    该行为需要一些客户端脚本:首先,我们要添加一个函数来获取一个随机数,然后根据该随机数设置TextBox的背景颜色.第二,我们要定义要用到的color数组.我们可以轻而易举的绕开外部文件,直接向页面注入要用到的JavaScript.下面的代码显示了FunkyTextBox控件的完整代码(为简化起见,using声明、命名空间、以及定义好的colors数组都省略掉了)

    public class FunkyTextBox : TextBox
    {
        protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
        {
            // Wire up the onkeypress event handler to the ChangeBackgroundColor() JavaScript function
            writer.AddAttribute("onkeypress", "ChangeBackgroundColor(this);");

            base.AddAttributesToRender(writer);
        }


        protected override void OnPreRender(EventArgs e)
        {
            // Dump in the JavaScript directly into the page
            // (Although the external JavaScript approach is more efficient)
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "FunkyTextBox",
    @"
    function ChangeBackgroundColor(ctrl)
    {
      var rndNum = Math.floor(Math.random() * 256);
      if (ctrl && funkyTextBoxColors.length > rndNum)
        ctrl.style.backgroundColor = funkyTextBoxColors[rndNum];
    }

    var funkyTextBoxColors =  new Array('#89C142', '#EF14E5', '#75762C', '#BB9E24', '#BF4A44', '#9D4A77', ...);
    ", true);

            base.OnPreRender(e);
        }
    }

    该server control继承自ASP.NET的TextBox,重写了2个方法.第一,在AddAttributesToRender方法里,添加了一个客户端特性(client-side attribute),那么任何时候,当用户在textbox控件里键入字符时,就会调用名为ChangeBackgroundColor的JavaScript function,传入对该textbox的引用.第二, 在FunkyTextBox的PreRender event事件里,通过 Page.ClientScript class's RegisterScriptBlock method方法直接将所需要的JavaScript注入到页面里.具体来说,定义了ChangeBackgroundColor function和funkyTextBoxColor数组,而ChangeBackgroundColor function获取一个随机值,再根据该值用funkyTextBoxColor数组里对应的颜色来设置背景色.

    当把FunkyTextBox添加到一个ASP.NET页面后,最终页面将包含如下的代码:

    <script type="text/javascript">
    <!--

    function ChangeBackgroundColor(ctrl)
    {
        var rndNum = Math.floor(Math.random() * 256);
        if (ctrl && funkyTextBoxColors.length > rndNum)
            ctrl.style.backgroundColor = funkyTextBoxColors[rndNum];
    }

    var funkyTextBoxColors =  new Array('#89C142', '#EF14E5', '#75762C', '#BB9E24', '#BF4A44', '#9D4A77', ...);
    // -->
    </script>


    Here is a FunkyTextBox:
    <input onkeypress="ChangeBackgroundColor(this);" name="MyTextBox" type="text" id="MyTextBox" />

    通过OnPreRender method方法将JavaScript注入到页面,而FunkyTextBox控件呈现为一个 <input type="text">标记,其onkeypress event事件调用ChangeBackgroundColor function函数.

    将JavaScript转移到一个外部文件以对页面瘦身

    该FunkyTextBox控件使用的JavaScript很简单,稍微复杂点的控件为实现其功能所需的JavaScript远不止这么多.直接将JavaScript植入页面将增大页面的size,也会让用户花更多的时间加载页面. 为了对页面瘦身,应将JavaScript转移到一个外部文件里,再在页面里添加一个<script>标签,以实现对JavaScript file的引用,比如:

    <script src="PathToExternalJavaScriptFile" type="text/javascript" >

    用<script>元素来替换JavaScript就达到了对页面瘦身的目的.此外,如果浏览器对外部文件实施缓存的话,那么我们就只需要下载一次就可以了(如果直接将JavaScript植入页面的话,每个页面每次登陆/加载时都要进行加载)

    在ASP.NET 1.x里,对这些外部资源文件——JavaScript文件、CSS classes, images等,都需要与custom control一起加载和展开.在ASP.NET 2.0里我们可以将这些外部资源植入该控件的装配件,再通过一个指定的URL实现对这些资源的访问.

    将外部文件植入控件的Assembly

    要将资源植入控件的装配件,我们需要在Visual Studio里把资源添加到你的server control project里(本文结尾处可下载的代码里,包含了FunkyTextBox Web control Project,以及一个test website).对FunkyTextBox控件来说,我添加了一个名为Funky.js的文件,它包含的JavaScript就是我们在前面的OnPreRender方法向页面注入的那个JavaScript..

    完成添加后,在Solution Explorer里选中它并打开Properties窗口,将Build Action设置为"Embedded Resource", 如下图:

    这样一来,一旦你生成解决方案时,该文件就会被植入最终的assembly里.

    通过一个URL来访问Embedded Assembly


    对这些内置资源,我们可以通过WebResource.axd HTTP Handler来进行访问。通过一个URL,比如http://yoursite/WebResource.axd?d=assemblyKey&t=dateTimeOfLastAssemblyWrite, 其中,assemblyKey是要访问的装配件的名称的加密处理后的string, 而dateTimeOfLastAssemblyWrite描述了该装配件最后一次被修改的日期.给定一个有效的assemblyKey,那么WebResource.axd HTTP Handler就可以返回内置资源的内容.

    使用WebResource.axd HTTP Handler,我们要面临3个问题:

    1.通过WebResource.axd HTTP Handler,使一个内置资源允许被访问.
    2.向WebResource.axd HTTP Handler传递准确的querystring值,以便检索某个特定的内置资源
    3.将第2步生成的URL放置在ASP.NET页面恰当的位置

    默认情况下是不允许WebResource.axd HTTP Handler对装配件里的内置资源进行访问的,为重写该行为,我们必须向server control project的AssemblyInfo文件添加一个特性(attribute),具体来说,要添加一个WebResource特性,比如:

    [assembly: WebResource(webResource, contentType, performSubstitution)] 

    注意:如果你使用的是Visual Basic,那么你需要用“<”和“>”来限定装配件,比如<assembly: WebResource(...)>.要看该AssemblyInfo文件的话,在Solution Explorer里选"Show All Files",它出现在 "My Project"文件夹下;再者,WebResource特性位于System.Web.UI命名空间,因此我们要在AssemblyInfo.cs文件顶端添加using System.Web.UI声明(如果是VB的话,用Imports System.Web.UI).

    其中webResource参数指定了要访问的资源的名称,其命名模式为:RootNamespace.PathToFile.对本文示例而言,根命名空间为FunkyTextBox;又因资源文件在工程的根目录下,那么PathToFile就是Funky.js(假如Funky.js位于根目录的Scripts文件夹,那么PathToFile值就变成了Scripts.Funky.js).因此,webResource参数的值就为FunkyTextBox.Funky.js.

    而contentType参数指定了要检索的资源的MIME type.当查询一个外部资源时,浏览器单独向服务器发出一个HTTP request.而MIME type就告知浏览器要返回的数据的类型.对JavaScript文件而言,其对应的contentType类型为text/javascript,有关MIME Media Types的更多信息,请参阅官方的MIME types清单.

    最后,performSubstitution是一个可选的布尔值,用于指明该资源是否可以被其它的外部资源引用.比如,你可能将image文件和一个JavaScript文件植入到了装配件里,而该脚本文件可能需要引用某些image资源.如果确实需要的话,就将performSubstitution参数设为True.

    对本文用到的控件而言,我们用如下的attribute声明来对Funky.js外部文件注册:

    [assembly: WebResource("FunkyTextBox.Funky.js", "text/javascript")]

    对资源进行注册后,我们就可以用WebResource.axd HTTP Handler来对其进行访问了.剩下的工作就是写代码来生成该外部资源对应的相应URL.

    为此,我们使用ClientScriptManager class类里的GetWebResourceUrl(type, webResource) method方法.其中type参数就是该控件的类型,

    webResource参数就是前面的WebResource特性里使用的webResource的值. 比如,要获取一个从该server control里访问内置的Funky.js资源的URL,我这样实现:

    Page.ClientScript.GetWebResourceUrl(this.GetType(), "FunkyTextBox.Funky.js")

    另外,我们在FunkyTextBox控件的OnPreRender事件里,将RegisterClientScriptInclude 方法和GetWebResourceUrl方法搭配使用,将相应的JavaScript包含进来(<script src="PathToExternalJavaScriptFile" type="text/javascript" >),如下:

    protected override void OnPreRender(EventArgs e)
    {
        // When pre-rendering, add in external JavaScript file
        Page.ClientScript.RegisterClientScriptInclude("FunkyJavaScript",
                     Page.ClientScript.GetWebResourceUrl(this.GetType(),
                                                 "FunkyTextBox.Funky.js"));

        base.OnPreRender(e);
    }

    通过这个重写的OnPreRender方法,控件将向页面添加如下的标记:

    <script src="/TestWebsite/WebResource.axd?d=NLu6bm6a2XinJZt4M-ujmQ13X5ALig6NEAZa1-AxV0HCbE3M-

    VHNomDQt_qnxjdT0&t=632902136868023078" type="text/javascript"></script>

    Here is a FunkyTextBox:
    <input onkeypress="ChangeBackgroundColor(this);" name="MyTextBox" type="text" id="MyTextBox" />

    这样就将JavaScript引进来了.WebResource.aspx HTTP Handler获取该内置资源并将其发送回客户端.

    结语

    本文我们考察了如何将资源植入一个自定义ASP.NET server control的装配件里,以及如何通过一个URL来访问这些资源.这是ASP.NET 2.0里的新技术,便于开发者将外部资源植入装配件.

  • 相关阅读:
    8皇后问题
    初级8皇后问题
    某个集合的子集问题
    n全排列输出和 n个数的组合(数字范围a~b)
    (转)李明博:我的12年等于24年 快速提升的秘诀是什么 别人以为我早起是先天的,事实靠的是努力 训练,除了反复的努力之外没有什么别的秘诀 像企业主一样去思考,一样查找问题,一同去解决它,并且还要制定出比企业主要求更高的目标。李明博像我一样,不,他比我更把公司当成自己的
    (转)当别人努力的时候,你在做什么? 评论事情的一种态度 当你在抱怨的时候,为什么不想想我做了什么? 把简单的原则坚持贯彻下去 消极的心态,养成了惯性的思维,一切都是不好的。 也许这就是人性的弱点,不经意的习惯,却逐渐腐蚀了你的人生。
    对于保险的看法和如何拒绝保险推销 保险应该主要是有2个主要作用: 1. 分担风险 2. 投资 保险的常用推销方法和该保险的卖点 拒绝保险的方法
    业务、架构、技术,我们应该关注什么 Java和.Net的优势劣势简单看法 市场经济决定,商业之道即是软件之道,市场的需求决定着软件技术的发展 利益决定着选择应用新技术
    我的学习工作经历,一个园林专业中专毕业生的IT之路 学习编程 创业
    “医疗信息化行业之中的联发科”- 我们在医疗行业中的定位及目标 想做一个面对中小企业的专业上游软件供应商 台湾联发科技颠覆掉的是一个封闭的手机产业系统 解决方案,即AgileHIS.NET数字化医院基础方案
  • 原文地址:https://www.cnblogs.com/invinboy/p/1313327.html
Copyright © 2011-2022 走看看