玩转C科技.NET

每天都在学习,每天都在退步 为什么?世界发展太快! 怎么办?加快学习速度! 如何做?关注.NET社区 进阶中……

导航

<2008年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

公告

Subscribe to this feed
Contact volnet online!

MSN群MyMSDN技术讨论群
群号:www.msdn@hotmail.com
Windows Live Alerts
欢迎大家踊跃加入讨论任何与技术有关的问题。
————————————
欢迎给我发送邮件:
volnet@tom.com
[标题格式]:[TO玩转C科技]<您的用户名/匿名>[<主题>]
————————————

 
您可以直接Gmail联系我噢!(Gtalk/Mail)
开机自启动,天天都在线哦!

LiveMessenger:
<My Library>

与我联系

搜索

 

常用链接

留言簿(4)

我参与的团队

我的标签

随笔分类(119)

随笔档案(105)

文章分类(15)

文章档案(15)

相册

家园建设

最新随笔

积分与排名

  • 积分 - 148605
  • 排名 - 243

最新评论

阅读排行榜

评论排行榜

如何使用ASP.NET2.0的“嵌入的资源”

关于嵌入的资源在MSDN已经有一些基本的介绍:“嵌入的资源”(ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_csexpresscon/html/f42dff1c-6804-4fda-94e5-1e77460a9142.htm)

这里我们要介绍的内容将让这些资源变得更加简洁。

通常我们在ASP.NET2.0中使用嵌入的资源的时候只需完成以下几步:

1.添加资源文件,如:

resource

2.将资源文件的编译方式变为“嵌入的资源”,如:

embededResource

3.添加Assembly信息(AssemblyInfo.CS或者在具体类的namespace之上),如:

[assembly: System.Web.UI.WebResource("IntelligenceTextBox.JScript.IntelligenceTextBox.js", "application/x-javascript")]
[assembly: System.Web.UI.WebResource("IntelligenceTextBox.CSS.IntelligenceTextBoxStylesheet.css", "text/css")]

4.将资源文件注册到页面文件中(在protected override void OnPreRender(System.EventArgs e)里),如:

Page.ClientScript.RegisterClientScriptResource(this.GetType(), "IntelligenceTextBox.JScript.IntelligenceTextBox.js");

完成这一步后的脚本文件就会在PreRender的时候输出到前台Html中。如:

<script src="/WebResource.axd?d=XBIPl09lmgYKinSg7vem6zAjPh9zda0B5YvbMz9cdk-Dtoq3pnz_VUoa1-xOFpiq0&amp;t=633419848307656250" type="text/javascript"></script>
这样就可以在页面文件中引用相关的资源文件中的内容了。
但是我们注意到RegisterClientScriptResource在生成的时候都会当作application/x-javascript来输出,因此最终都只能得到type="text/javascript",而这样的设置则不符合其他类型资源的输入规则。为此我构建了下面这个类,仅完成了MetaType类型为text/css的资源的输出,但它很容易扩充成支持各种格式的类型,而扩充需要您做的事很少。引入资源的方式却十分简单。
思路:
添加资源到页面,无非就是做到如上所示的1到4点,而唯一要解决的就是不同的metaType所特定的格式不同,如:
CSS:
<link href="{0}" rel="stylesheet" type="text/css"/>
JavaScript:
<script src="{0}" type="text/javascript"></script>
而我们的期待的表现形式则形如上文第4点所示的方式,另外需要解决的一个问题是一个页面多个资源不用重复注册的问题。
是否添加重复资源的问题应该留给用户自行解决,因此通过提供IsResourceRegistered方法给用户进行自行判断。
[下面的代码需要经过改造后才能通过.NET2.0编译器的编译,否则默认使用.NET3.0以上编译器可以编译,请见谅!]
调用代码(示例):
        protected override void OnPreRender(System.EventArgs e)
        {
            base.OnPreRender(e);
            if (Page != null)
            {
                ClientScriptHelper cs = new ClientScriptHelper(this.Page);

                string cssName = "IntelligenceTextBox.CSS.IntelligenceTextBoxStylesheet.css";
                if (!cs.IsResourceRegistered(cssName))
                    cs.RegisterResource<IntelligenceTextBox>(this, ClientScriptHelper.MetaType.TextCSS, cssName);
                //Page.ClientScript.RegisterClientScriptResource(this.GetType(), "IntelligenceTextBox.JScript.IntelligenceTextBox.js");
                string jsName = "IntelligenceTextBox.JScript.IntelligenceTextBox.js";
                if (!cs.IsResourceRegistered(jsName))
                cs.RegisterResource<IntelligenceTextBox>(this, 
                    ClientScriptHelper.MetaType.TextJavaScript,
                    jsName);
            }
        }
源代码:
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;

namespace IntelligenceTextBox
{
    internal class ClientScriptHelper
    {
        private IDictionary resourceActuals;

        /// <summary>
        /// Get the parent container (page) reference.
        /// </summary>
        /// <param name="container"></param>
        public ClientScriptHelper(Page container)
        {
            resourceActuals = container.Items;
        }

        /// <summary>
        /// Reigister the resource to the page.
        /// </summary>
        /// <typeparam name="T">The type of resource.</typeparam>
        /// <param name="sender">The resource.</param>
        /// <param name="metaType">The metaType of the resource.</param>
        /// <param name="resourceName">The name of the resource.</param>
        public void RegisterResource<T>(T sender, MetaType metaType, string resourceName)
            where T : Control
        {
            ResourceInfo resourceInfo = ResourceHtmlTemplateFactory(metaType, sender.Page);
            if (sender != null)
            {
                Literal resourceLiteral = new Literal();
                resourceLiteral.Text = string.Format(resourceInfo.HtmlTemplate,
                    sender.Page.ClientScript.GetWebResourceUrl(typeof(T), resourceName)
                );

                resourceInfo.Where.Controls.Add(resourceLiteral);

                if (!resourceActuals.Contains(resourceName))
                    resourceActuals.Add(resourceName, resourceLiteral);
            }
        }

        /// <summary>
        /// Make sure is the resource has been registered in the current Page.
        /// </summary>
        /// <param name="resourceName">The name of the resource.</param>
        /// <returns></returns>
        public bool IsResourceRegistered(string resourceName)
        {
            return resourceActuals.Contains(resourceName);
        }

        /// <summary>
        /// The factory to create the right ResourceInfo for render.
        /// </summary>
        /// <param name="metaType">MetaType of the resource.</param>
        /// <param name="container">The page will contain the resource</param>
        /// <returns></returns>
        private static ResourceInfo ResourceHtmlTemplateFactory(MetaType metaType, Page container)
        {
            ResourceInfo resource = new ResourceInfo()
            {
                HtmlTemplate = string.Empty,
                Where = container.Header
            };

            if (metaType == MetaType.TextCSS)
            {
                resource.HtmlTemplate = "\n<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\"/>";
                resource.Where = container.Header;
            }
            else if (metaType == MetaType.TextJavaScript)
            {
                resource.HtmlTemplate = "\n<script src=\"{0}\" type=\"text/javascript\"></script>";
                resource.Where = container.Header;
            }

            //Todo: Add the other metatype ResourceInfo instance.
            
            return resource;
        }

        /// <summary>
        /// The infomation of resource depend on the metatype. 
        /// </summary>
        internal class ResourceInfo
        {
            /// <summary>
            /// The html syntax of the resource.
            /// e.g.
            /// text/css: \n<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\"/>
            /// </summary>
            public string HtmlTemplate { get; set; }

            /// <summary>
            /// The place to render the html syntax.
            /// </summary>
            public System.Web.UI.HtmlControls.HtmlControl Where { get; set; }
        }

        /// <summary>
        /// MetaType
        /// </summary>
        public enum MetaType
        { 
            TextCSS,
            TextJavaScript
        }
    }
}
Tag标签: Control

posted on 2008-03-24 21:40 volnet(可以叫我大V) 阅读(2179) 评论(14)  编辑 收藏 所属分类: C# ControlsASP.NET

评论

#1楼  2008-03-24 21:52 缤纷      

有没有更好的办法实现呢?   回复  引用  查看    

#2楼 [楼主] 2008-03-24 22:03 volnet(可以叫我大V)      

@缤纷
希望有吧,呵呵   回复  引用  查看    

#3楼  2008-03-25 08:32 武眉博<活靶子.Net>      

我记的签入css文件后 不用再做其他的,当控件被从control box拖到aspx上时候,自己就在head内生成<link hrer=...了。   回复  引用  查看    

#4楼  2008-03-25 09:27 远航      

通过获取GetWebResourceUrl()资源,然后添加到头元素中,不就可以了。   回复  引用  查看    

#5楼 [楼主] 2008-03-25 16:18 volnet(可以叫我大V)      

@武眉博&lt;活靶子.Net&gt;
你的这个不需要用到我的这个:)
我这种适合于将css文件等资源嵌入在控件的内部进行使用。
这样的好处有
1.可以更好地封装,那些脚本本来就属于控件本身,不可能要求它的用户手动加入它
2.这样做更方便了,也利于IE这样的浏览器缓存它。

@远航
其实我就是这么做的,只不过想省去那么一点点套路,既然是套路,就封装起来会更好   回复  引用  查看    

#6楼  2008-03-25 19:39 nicye      

http://www.cnblogs.com/kellynic/archive/2008/03/25/1121753.html

看下这个吧   回复  引用  查看    

#7楼 [楼主] 2008-03-26 10:10 volnet(可以叫我大V)      

@nicye
广告?   回复  引用  查看    

#8楼  2008-05-29 21:47 wauo [未注册用户]

觉得这里不能用static 来存储,建议换成Page.Items来存储   回复  引用    

#9楼 [楼主] 2008-05-30 02:04 volnet(可以叫我大V)      

@wauo
我个人觉得静态在这里可以使用,至于是不是最好不做评论,Page.Items,因为这东西基本会用在控件上,在做控件的时候我们为什么要有Page呢?当然实际情况中是一定有Page的……   回复  引用  查看    

#10楼  2008-05-30 21:27 wauo      

只是考虑到static 字段被多个实例共享,如果页面第一次把资源记录到static 字段,再刷新页面就不会输出资源了,因为IsResourceRegistered将返回true~~是不是会有些问题~~~瞎掰下,错了请见谅   回复  引用  查看    

#11楼 [楼主] 2008-06-02 02:09 volnet(可以叫我大V)      

@wauo
说的貌似在理,非常感谢啊,一时没有注意到,呵呵   回复  引用  查看    

#12楼  2008-06-17 22:23 ColdDog      

我的VS2005(没装sp1)第2步怎么没有“生成操作”这个属性?需要SP1?
VS2008就有。。。   回复  引用  查看    

#13楼 [楼主] 2008-06-18 01:03 volnet(可以叫我大V)      

@ColdDog
呵呵,已经不记得2005 without SP1的样子了,您还是尽快升级SP1吧,或者直接换用2008比较好,呵呵   回复  引用  查看    

#14楼  2008-06-20 13:31 ColdDog未登录 [未注册用户]

已经搞定了,呵呵,谢谢大V   回复  引用    

使用Live Messenger联系我
关闭