zoukankan      html  css  js  c++  java
  • 谈谈ASP.NET模版(皮肤)机制的实现

    做一个WEB程序,能够在尽量修改极少程序代码的情况下,轻松制定皮肤以及切换皮肤,应该都是需要的,谁也不想,在网站界面想要改版的时候,要改一大片逻辑代码。 一个合格的皮肤机制体系的实现,应该要做到以下几点: ->页面模板上要极少拥有逻辑代码(如果模板上拥有大量逻辑代码,那估计这个也不叫作模板了)。 ->能够轻松改变页面布局,同时不影响程序代码(.cs)。 ->新模板的定制,基本上能由皮肤制作者参照旧模板自行完成,不需要开发人员太多介入。 ->保持性能。 然后,来看看,都有哪些方法大家用来实现所谓的皮肤机制,同时进行各个方法的一些个人说明。   1. 改变页面调用的CSS文件来换肤。 这一个,严格上来讲,不应该算作皮肤机制。虽然CSS非常强大,也能够通过它来任意改变页面元素布局,但它的HTML始终是不变的,所以局限性是非常大的。 优点:完全不影响性能,甚至可以完全不由服务端代码来管理它的变换,可以使用JS来切换皮肤(由此,在我们有一套完美皮肤机制的情况下,这种方法,可以完全不与此机制冲突,让用户在客户端作更多的个性化)。 缺点:如果作为核心皮肤机制的话,非常有局限性。 示例:如QQ.COM, 114LA.COM上面的一些可点击的小色块,就是改变调用的CSS文件来实现换肤。   2. 读取模板文件,替换标识符为要显示的内容与数据输出。 这一个方法的灵活性比较高,每套皮肤可以有自己的布局,有自己的个性。 实现:比如模板中有一个标识$Subject,程序代码会把它替换成文章标题,然后有一个标识块<!—Loop[ArticleList]--><h1>$Subject</h1><div>$Content</div><!--/Loop-->,程序代码会把它替换成一个文章列表,最后输出处理完所有标识符的内容。 通常,我们会缓存读取到的模板内容,但字符串的替换始终不可避免,或者也会把替换过的内容也缓存起来,但这样子,就等于要缓存模板内容以及替换过的内容,占用了两份似乎挺重复内容的内存(为什么?不然总不该每次数据有改变的时候就去作IO操作读取操作读模板文件吧,这似乎比字符串替换性能更差)。 优点:模板灵活程度很高,可以随便改动页面布局。 缺点:影响性能,开发人员维护难,必须有特定的标识符来表示页面变量,后期维护可能会带来非常多的问题。   3.使用ASP.NET的App_Themes。 这一个方法,应该是极差的一个方法,根本只是ASP.NET的一个小纂头,鸡肋,基本上不实用。 实现:比如,定制一个BUTTON的样式是这样子的,<asp:buttonrunat="server" BackColor="lightblue"ForeColor="black" />,类似这样的代码,存在于.skin文件中。然后它的换肤机制如下,<%@ Page Language="C#" Theme="default" %>。在App_Themes目录下,是各套皮肤的独立文件夹,各个文件夹包含皮肤的样式以及图片文件等等,也可以包含.skin文件。 优点:只有ASP.NET才有 缺点:包含了第一种方法的缺点,.skin的样式定制方式还要严重依赖使用ASP.NET服务端控件,同时也影响性能,灵活性也极低。   4.动态载入.ASCX文件(ASP.NET用户控件)|| 使用.master(母版)。 这个方法,应该也是很多使用ASP.NET的人使用的方法,有时候,它还会与第三种方法结合使用。如果对性能需求不是很严格的话,中小型项目可以使用。 实现:使用LoadControl()动态载入.ASCX文件或(与)指定页面的MasterPageFile(目标皮肤文件夹的)实现(通常.ascx与.master还会结合使用)。 优点:灵活性极高,每个皮肤有独立的布局,直接使用了.CS文件的变量与方法ETC…甚至每套皮肤还有自己独立的代码文件。 缺点:影响性能。有兴趣可以自己去反编译LoadControl方法。同时,在页面要使用<%%>这种代码块,有时候感觉也有点不雅。   5.Xml + xslt 传说xml取代html是趋势??不清楚,不了解。应该不可能。此种方法我没有深入了解过,不过大概实现应该是要这样子?每一个XML(输出数据)会有一个对应的XSL文件(控制样式)。如下: xml文件: <?xml version="1.0"encoding="ISO-8859-1" ?> <breakfast_menu> <food> <name>Belgian Waffles</name> <price>$5.95</price> <description>two of our famous Belgian Waffles with plenty of real maplesyrup</description> <calories>650</calories> </food> <food> <name>Cakes</name> <price>$1.95</price> <description>sweet cakes</description> <calories>2650</calories> </food> </breakfast_menu>   xsl文件: <?xmlversion="1.0" encoding="ISO-8859-1" ?> <html xsl:version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns="http://www.w3.org/1999/xhtml"> <body style="font-family:Arial,helvetica,sans-serif;font-size:12pt;background-color:#EEEEEE"> <xsl:for-each select="breakfast_menu/food"> <div style="background-color:teal;color:white;padding:4px"> <span style="font-weight:bold;color:white"> <xsl:value-of select="name" /> </span> <xsl:value-of select="price" /> </div> <divstyle="margin-left:20px;margin-bottom:1em;font-size:10pt"> <xsl:value-of select="description" /> <span style="font-style:italic"> <xsl:value-of select="calories" /> </span> </div> </xsl:for-each> </body> </html> 这样子做,有什么好处么,我没有体验到。   6.读取模板文件,生成.aspx文件到每套皮肤的独立文件夹下,通过地址重写指定到这些文件夹。 这个方法的最终效果对于用户来说,和第二种方法应该是差不多的,优点就是性能比较高,而且还能直接使用.CS代码里面的变量方法ETC…另外,也可以不会有<%%>代码块的存在,可以存在自己的模板语言,如同第二种方法的$Subject, <!—Loop-->标识符一般。 优点:几乎不影响性能,只有第一次读取生成.ASPX文件需要损失性能。灵活性极高。模板代码可读性也可以实现到很高。 缺点:启动时需要读取分析时间(不过,这应该算是小问题),另外,有一套皮肤,它就要生成与之对应的一套.ASPX文件(当然这个可以解决)。   7.利用ASP.NET2.0开始才拥有的VirtualPathProvider来实现。 虚拟文件机制。这个,应该算是第六种方法的加强版。最终的效果,和第六种差不多,只是不会生成那些.ASPX文件而已,取而代之的,便是长驻在内存中。 实现:实现两个类,一个继承至VirtualPathProvider,一个继承至SkinFile。VirtualPathProvider里有个FileExists方法,重写成判断请求的路径是否是皮肤文件路径,如果是,GetFile就实例一个SkinFile(这一个SkinFile,我们会对模板进行处理,可以拥有自己的模板语言)。另外有一个GetCacheDependency方法,可以来将模板文件作为虚拟文件机制的缓存依赖文件,一旦模板文件被修改了,它就会再重新解析模板文件。这里先不作赘述,具体的,查看MSDN的相关文档,具可了解。 优点:与6相同。 缺点:第一次启动需要损失性能(但这也不可避免)。   8.还有更多的实现方法,还没用过,个人先不发表观点,比如:使用BuildProvider,但这一个,需要有比较强的词法分析与语法分析能力。
  • 相关阅读:
    【Azure Redis 缓存】Azure Redis 功能性讨论二
    【Azure Developer】如何用Microsoft Graph API管理AAD Application里面的Permissions
    【Azure 环境】通过Python SDK收集所有订阅简略信息,例如订阅id 名称, 资源组及组内资源信息等,如何给Python应用赋予相应的权限才能获取到信息呢?
    【Azure 应用服务】App Service与APIM同时集成到同一个虚拟网络后,如何通过内网访问内部VNET的APIM呢?
    【Azure 云服务】如何从Azure Cloud Service中获取项目的部署文件
    【Azure Redis 缓存】Azure Redis 异常
    【Azure 微服务】基于已经存在的虚拟网络(VNET)及子网创建新的Service Fabric并且为所有节点配置自定义DNS服务
    【Azure Redis 缓存】遇见Azure Redis不能创建成功的问题:至少一个资源部署操作失败,因为 Microsoft.Cache 资源提供程序未注册。
    【Azure Redis 缓存】如何得知Azure Redis服务有更新行为?
    【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
  • 原文地址:https://www.cnblogs.com/micua/p/3502628.html
Copyright © 2011-2022 走看看