• ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理


      对于一个应用来说界面的重要性无言而喻,而Web应用的界面是使用Html+Css以及Javascript实现的,ASP.NET MVC是一个用来构建Web应用的框架,它的界面也是Html实现的,对于一些开发团队来说,一般Web项目会存在专业的UI前端工程师和后端工程师,前端工程师可能只懂设计和Html,但是对于如何将设计好的Html应用到ASP.NET可能就需要ASP.NET工程师的帮助。
      本文将介绍如何将已经设计好的Web界面应用到ASP.NET MVC中以及如何对这些资源文件进行管理,先看一下修改后的效果:

      

        

      本章的主要内容有:
      ● 素材选择
      ● ASP.NET MVC的界面布局及界面实现
      ● 使用BundleConfig进行素材资源管理
        ○ 使用bundle对素材分类
        ○ 使用Bundle对资源文件进行优化
        ○ 在Bundle中使用通配符及文件版本(min版)的选择
        ○ 使用CDN
        ○ Bundle中的缓存
        ○ Bundle重写样式表中资源引用路径
        ○ 自定义资源转变(Transform)
      ● 小结

    素材选择

      本文选取开源主题Start Bootstrap - Clean Blog为例进行介绍。
      Clean Blog是一个现代风格的响应式主题,基于bootstrap 4.0,下图为Clean Blog的运行效果:

      

      将Clean Blog下载到本地并导入《My Blog》项目中,该主题中包含了相应的样式表、图片、Js、示例页面等文件:

      

      注:Clean Bolg的GitHub地址:https://github.com/BlackrockDigital/startbootstrap-clean-blog

    ASP.NET MVC的界面布局及界面实现

      Clean Blog是由Html、Css、Javascript文件组成的一个静态Web界面,要将其应用到ASP.NET MVC中,只需要对其结构进行分析后一一替换到ASP.NET MVC的View中即可。
    所以首先要分析的是Clean Blog以及My Blog应用的页面布局,对于Clean Blog来说它分为三块,分别是导航、内容以及页脚:

      

      同样的My Blog之前使用的ASP.NET MVC默认模板也是分为了导航、内容和页脚:

      

      对于上面的布局来说,导航和页脚部分是不变的,只有中间的内容是变化的,在ASP.NET MVC中提供了布局页的机制,专门用来定义页面布局,将不变的内容放置在该布局页面上,所以要更换界面首先需要的就是定义布局页面:
      在Views/Shared目录下添加一个新的布局页面,将Clean Blog的Index页面中的导航以及页脚代码复制到新的布局页面中,包括css以及js的引用(注:需要修改路径),页面内容部分使用@RenderBody()方法代替:

      

      同时将_ViewStart.cshtml中指定的布局文件改为新创建的CleanBlog布局文件:

      

      最后参照Clean Blog内容页样式完成相应内容页面修改即可,下面以“联系我们”页面为例:

      

      运行效果(注:没有实现原主题中的信息提交功能):

      

      

    使用BundleConfig进行素材资源管理

      通过上面的介绍知道了如何通过布局页面来搭建页面内容,Web页面除了本身的Html代码外还少不了css、JavaScript等文件的支持,但这些文件都是相对零散的,在ASP.NET中有一个Bundle机制专门用于管理这些资源文件。
      Bundle有捆和包的意思,而在ASP.NET MVC中它实际就是可以将一组css或JavaScript捆绑起来,捆绑可以根据资源的一些特性进行归类,与此同时还添加了一些有用的附加功能,如:文件最小化、资源文件的版本管理、使用CDN加速、资源文件的缓存等等,下面就介绍如何使用bundle来管理新添加到项目中的素材资源。

    使用bundle对素材分类

      为了保证页面样式一致,所以在创建布局文件时添加了全站共用的样式和脚本,Clean Blog是基于Bootstrap4.0建立的,除此之外还有一些特殊的内容,如下图所示,它的实例代码中已经进行过分类:

      

      样式主要包括Bootstrap的核心样式、模板中使用的字体以及模板中的自定义样式,同样JavaScript除了bootstrap必要的JavaScript外还有自定义的JavaScript。根据这个分类规则,在App_Start/BundleConfig的BundleConfig类型中注册分类:

      样式分类:

      

      脚本分类:

      

      注:建议bundle的地址以bundles作为前缀,避免与路由冲突。
      完成后在布局文件中改用Bundle渲染样式和脚本:

      

    使用Bundle对资源文件进行优化

      前面通过Bundle对资源进行了分类,当同一类资源下存在多个文件时,页面只需要一句代码就可以全部引入使代码更清晰,当然Bundle机制在资源分类的同时,更重要的是可以对资源文件进行优。
      这里的优化有两个点分别是文件请求的优化和文件大小的优化,前者是将同一类的文件进行合并,合并成一个文件,在请求时只需请求一次即可,后者是将css及JavaScript中不需要的字符删除、变量名称简写以达到缩减文件尺寸的目的。
      使用Bundle管理资源时,在Release模式下将自动进行优化,另外也可以设置BundleTable.EnableOptimizations为true进行强制优化,如下图所示:

       

      运行时将可以看到如下结果:
      1. 请求数量减少:

      

      2.非最小化的js文件被最小化,如clean-blog.js:

      

      注:上面请求中出现字体文件无法找到的错误将在后续内容解释。

    在Bundle中使用通配符及文件版本(min版)的选择

      对于一些样式或脚本组件来说,它本身就可能由多个文件构成,如下图中的Jquery目录中就有jquery.js以及jquery.slim.js两个文件:

      

      在一些复杂的应用中还可能会使用到jQuery的其它组件,这样资源文件会更多,为了简化Bundle对资源的归类,在使用Bundle注册分类时,可以使用通配符来一次匹配多个文件:

        

      注:Bundle中能识别的通配符有两种,常用的就是“*”,另外还可以通过“{version}”来匹配文件版本。更多通配符相关内容可参考:https://docs.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification#using-the--wildcard-character-to-select-files
      直接使用*通配符可以匹配相应目录下的所有文件,下图是运行结果:

      

      从图中可以看到,比之前的请求中多了一些js文件,这些文件就是通过通配符匹配到的,但要注意的是这里没有获取包含.min版本的js文件,在相同目录下clean-blog.js以及jquery.js都有被最小化的min版本:

      

      Bundle机制会根据debug/release模式或者BundleTable.EnableOptimizations属性来判断是否对资源文件优化,在release模式(web.config中compilation的debug属性为true)下或者BundleTable.EnableOptimizations设为true时会启用资源优化,这里的资源优化除了上面提到的多个文件捆绑外,如果文件列表中有min版本文件,那么就会优先选择min版本文件。
      由于优化模式下无法看到具体请求的文件名称,所以在clean-blog.min.js中添加一条日志输出代码:

      

      然后使用release模式运行程序,将会获得下面结果:

      

      除了看到请求减少以外,还看到日志中输出了min版本文件中添加的内容,证明使用release模式运行时Bundle会自动选择文件最小化的版本。

    使用CDN

      CDN(内容分发网络),为了提高web的响应速度,其中一项主要的优化手段就是将静态资源放到CDN上,这样用户就可以在离他最近的网络节点获取到这些资源,这样既提高了资源获取的速度同时也降低了应用服务器的压力,ASP.NET中的Bundle可以为相应的资源配置CDN,并且该配置也是release模式下生效:

      

      使用CDN主要有以下几个步骤:
      ● 将bundles的UseCdn属性设为true。
      ● 创建Bundle对象时构造方法中传入CDN的路径。
      ● 设置Bundle对象的CdnFallbackExpression属性,该属性用于判断通过CDN加载的内容是否正确加载,如果没有那么会加载Include中的内容。

      运行效果:

      

      将bundles.CdnFallbackExpression的属性设置为window.jQuery会生成一个判断window.jQuery对象是否存在,如果不存在则获取服务器资源的代码:

      

      通过修改CDN资源路径,模拟CDN无法访问情况,它会自动加载可用的资源:

      

      CDN可用资源参考:http://www.bootcdn.cn/

    Bundle中的缓存

      在Release或资源优化模式下,Bundle为其管理的资源提供了缓存机制,在第一次访问Bundle管理的资源时,Bundle会为每一组资源生成一个唯一标识,然后将该资源默认缓存一年:

      

      当资源发生改变时唯一标识会发生变化,那么原来缓存的内容就自动失效了。

    Bundle重写样式表中资源引用路径

      在前面的介绍的过程中release模式下一直有一个错误,就是无法找到字体文件,这是因为在编写样式时会引入一些字体或者图片等外部资源,而这些资源一般是用相对路径进行引用的,但是当ASP.NET中使用Bundle来对样式资源进行捆绑时,该资源的url地址就发生改变了,导致使用该地址组合的引用资源的地址不正确,从而导致了资源无法加载:

      

      为了解决这一问题,Bundle提供了一个重写样式引用相对路径的解决方案,在将样式表注册到Bundle中时,可以为相应的样式文件添加一个CssRewriteUrlTransform对象,它用于Css文件优化时对其引用的Url进行重写:

      

      添加以上代码后,运行程序将解决字体无法找到的问题:

      

    自定义资源转变(Transform)

      资源转变是Bundle机制在优化资源时提供的一个可拓展接口,如上面介绍的css Url重写就是资源转变的拓展,Bundle中实现资源转变需要实现以下接口:

       

      接口中的参数分别代表获取到文件的虚拟路径和文件的内容。
      下面创建一个在css中插入自定义内容的资源转换器,来介绍如何实现资源转变的自定义拓展:
      实现IItemTransform接口,在样式文件中追加".test {color: red;}"样式:

      

      将该转换器通过Include方法应用到对应文件上:

      

      运行结果显示相应内容已经被添加到最终的样式文件中:

      

      注:IItemTransform接口是在资源优化前调用的,所以本例添加内容包含的空格和分号最终都被优化删除了,所以在使用IItemTransform进行拓展时需要注意资源优化问题。
      另外在Bundle中还有另外一个拓展接口IBundleTransform,它定义了一个用于转换Bundle相应文件的方法:

      

      实现Process接口,在响应的内容上添加注释“hello selim”:

      

      BundleTransform需要在Bundle的Transforms属性上添加:

      

      运行结果:

      

      相对与ItemTransform来说BundleTransform处理后的内容不会再进行优化,在文档https://docs.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification#less-coffeescript-scss-sass-bundling中还通过BundleTransform实现了less等文件动态编译的功能,有兴趣可参考该文档。

    小结

      本章主要介绍了如何将现有的Web样式应用到ASP.NET MVC中,并着重介绍了ASP.NET MVC中对静态资源管理的Bundle机制。Bundle机制除了可以对资源文件进行归类外还提供了资源文件优化、CDN、缓存等高级功能。合理的利用Bundle可以让项目代码更清晰,同时也可以提高应用的性能。

    参考:
      https://github.com/BlackrockDigital/startbootstrap-clean-blog
      https://html.com/attributes/
      https://docs.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification
      https://www.codeproject.com/articles/842961/introducing-dynamic-bundles-for-asp-net-mvc
      https://stackoverflow.com/questions/11355935/mvc4-stylebundle-not-resolving-images#
      http://www.bootcdn.cn/
      http://www.tutorialsteacher.com/mvc/scriptbundle-mvc
      https://www.codeproject.com/Articles/728146/ASP-NET-MVC-bundles-internals
      https://blogs.msdn.microsoft.com/rickandy/2011/05/21/using-cdns-and-expires-to-improve-web-site-performance/

    本文链接:http://www.cnblogs.com/selimsong/p/8589175.html 

     ASP.NET没有魔法——目录

  • 相关阅读:
    Power BI for Office 365(八)共享查询
    Power BI for Office 365(七) Power BI站点
    Power BI for Office 365(六)Power Map简介
    Power BI for Office 365(五)Power View第二部分
    Power BI for Office 365(四)Power View第一部分
    Power BI for Office 365(三)Power Pivot
    Power BI for Office 365(二)Power Query
    java 继承、重载、重写与多态
    Android 热修复方案Tinker(一) Application改造
    阿里最新热修复Sophix与QQ超级补丁和Tinker的实现与总结
  • 原文地址:https://www.cnblogs.com/selimsong/p/8589175.html
Copyright © 2020-2023  润新知