对于一个应用来说界面的重要性无言而喻,而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没有魔法——目录

ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理的更多相关文章

  1. ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理

    ASP.NET没有魔法——ASP.NET MVC Razor与View渲染   对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的 ...

  2. ASP.NET没有魔法——ASP.NET MVC Razor与View渲染

    对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的界面呈现工作是由浏览器完成的,Web应用的原理是通过Http协议从服务器上获取到 ...

  3. ASP.NET没有魔法——ASP.NET MVC 与数据库大集合

    ASP.NET没有魔法——ASP.NET与数据库 ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQL ASP.NET没有魔法——ASP.NET MVC 与数据库之ORM ASP.N ...

  4. ASP.NET没有魔法——ASP.NET MVC 路由的匹配与处理

    ASP.NET MVC的路由是MVC应用的一个核心也是MVC应用处理的入口,作为一个开发者,在正常情况下仅仅需要做的就是根据需求去定义实体.业务逻辑,然后在MVC的Controller中去调用.Vie ...

  5. ASP.NET没有魔法——ASP.NET MVC IoC

    之前的文章介绍了MVC如何通过ControllerFactory及ControllerActivator创建Controller,而Controller又是如何通过ControllerBase这个模板 ...

  6. ASP.NET没有魔法——ASP.NET MVC 过滤器(Filter)

    上一篇文章介绍了使用Authorize特性实现了ASP.NET MVC中针对Controller或者Action的授权功能,实际上这个特性是MVC功能的一部分,被称为过滤器(Filter),它是一种面 ...

  7. ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证

    随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...

  8. ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)

    上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...

  9. ASP.NET没有魔法——ASP.NET 身份验证与Identity

    前面的文章中为My Blog加入了文章的管理功能(ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块),但是管理功能应该只能由“作者”来访问,那么要如何控制用户的访问权限?也 ...

随机推荐

  1. Log4j2配置文件详解

    目录[-] 1 系列目录 2 默认配置 3 第一个配置例子 4 复杂一点的配置 4.1 Appender之Syslog配置 4.2 Syslog及Syslog-ng相关配置(Fedora) 5 Log ...

  2. python调用百度语音(语音识别-斗地主语音记牌器)

    一.概述 本篇简要介绍百度语音语音识别的基本使用(其实是斗地主时想弄个记牌器又没money,抓包什么的又不会,只好搞语音识别的了) 二.创建应用 打开百度语音官网,产品与使用->语音识别-> ...

  3. hdu 2048 递推&&错排

    直接贴出递推公式: cnt[n]=(i-1)*(cnt[n-1]+cnt[n-2]); 数组保存的是失败的种数 AC代码: #include<cstdio> const int maxn= ...

  4. 算法提高 金属采集 树形DP

    题目链接:金属采集 思路:d(i, j)表示在以i为根结点的子树中使用j个机器人的最小花费.设v为u的一个子节点,从节点i使用k个机器人收集以v为根结点的能量,状态转移方程为d(u, i) = min ...

  5. kubernetes 命令使用

    学会命令的查找和使用,而不是死记命令,记命令不如提高英文水平 1.kubernetes环境搭建完成后,kubernetes环境搭建参考http://www.cnblogs.com/sosogengdo ...

  6. 在SpringBoot中使用FluentValidator验证插件

    前言 在我们编写项目的时候,在controller中往往离不开对一些数据的校验.这里并不是说对于这些数据业务上面的校验,而是对这些数据进行空校验或者是长度校验等. 有些时候校验可以省略,根据业务的需要 ...

  7. 基础--Linux环境下一键部署 lnmp

    1. 通过x-shell 或者 putty 登录服务器 2. 下载lnmp一键安装包 >wget -c http://soft.vpser.net/lnmp/lnmp1.4.tar.gz  # ...

  8. 3.3.2 PCI设备对不可Cache的存储器空间进行DMA读写

    在x86处理器和PowerPC处理器中,PCI设备对"不可Cache的存储器空间"进行DMA读写的过程并不相同.其中PowerPC处理器对"不可Cache的存储器空间&q ...

  9. 小说接入UC浏览器内核技术对话(二)

    质辛@灿岩 质辛跟我们说一下那个删除文件的逻辑吧质辛@灿岩  应该不是删除cache下所有文件吧?质辛质辛@智鹰  提供一下我们的临时文件完整路径给 灿岩吧质辛@智鹰  是负责我们ucsdk的 技术对 ...

  10. LINUX下printf输出字体的特效

    在学习LINUX网络编程的时候我们做了一个聊天系统,当时为了界面更漂亮点,于是在百度上搜索了下关于printf()函数的用法,和大家分享下:                           给pr ...