阅读目录:
- 1.开篇介绍
- 2.System.Web.Optimization 组件
- 3.System.Web.Optimization 组件基本原理
- 4.扩展自定义类型静态文件
1】开篇介绍
这篇文章将简单的分析一下有关静态文件捆绑的ASP.NET组件System.Web.Optimization的运行原理及基本的缓存问题;
在我们的项目里面充斥着很多静态文件,为了追求模块化、插件化很多静态文件都被设计成模块的方式或者被分解,在需要的时候在通过组合的方式在UI层上使用;这就带来一个问题,文件多了会影响浏览器加载页面的速度,而且由于浏览器的并发限制,对于并行的请求不是无限制的,所以捆绑静态文件的功能就产生;其实在以前,IIS还没有集成管道模型的时候我们只能通过动态资源的方式进行输出,也就是我们经常在*aspx页面里看见很多*.axd结尾的请求,当然多数情况下是配合ASP.NETAJAX用来输出动态JS、HTMDOM、CSS用的;
最新的IIS已经很好的集成了ASP.NET管道模型,也就是说我们完全可以通过ASP.NET本身的扩展来控制所有经过IIS的请求,包括静态文件,所以让捆绑静态文件成为了可能;
下面我们将分析一下System.Web.Optimization组件的基本运行原理,它是如何动态加载的,如何控制缓存的;
2】System.Web.Optimization 组件
每当我们新建一个ASP.NETMVC4站点的时候都会在~/App_Start目录下有一个BundleConfig.cs的启动文件,当然创建其他的ASP.NET4.0及4.0以上的项目也会有;
我第一次看见这个文件实在让我困惑,所以我打算简单的分析一下,知道其基本原理;
代码是一个静态方法,然后传入一个BundleCollection集合对象,其实就是Bundle对象的集合,然后通过向集合内部注册多个Bundle;每个Bundle对应着多个静态文件,可以想象成就是键值对集合;通过后面的Include方法包含N多个静态文件,这里的静态文件路径可以是符合特定规则的字符串,由它内部去计算;
这是注册阶段,然后就是使用阶段,使用阶段很简单只要我们通过我们注册的Key字符串就能直接引用这些静态文件列表;
我们只要关注Styles.Render、Scripts.Render两个方法,这两个方法是想页面注入之前在后台配置的静态文件列表;这样我们在客户端看见的就是被捆绑过后的文件集合了;
文件的连接地址已经是被捆绑过后的地址了,这个地址就是我们在之前注册的时候用的key,后面它需要这个key去获取value 静态文件列表;要想你的捆绑起效果需要在注册的时候加上一段:BundleTable.EnableOptimizations = true;代码,意思是说开启捆绑,如果不开启捆绑则默认在调试环境里将不起效果,因为System.Web.Optimization使用了默认捆绑策略,如果是在Debug模式下,将不启用捆绑,如果你人为的设置了将覆盖默认设置;
使用就是这些,下面我们需要搞懂它是如何运行的,要了解一下它的基本原理;
3】System.Web.Optimization 组件基本原理
既然IIS集成了管道模型,那么我们肯定是能找到对应的HttpModule的,为了节省时间我就不去下载源码了,我们直接用反编译工具看一下;
这就是Bundle的HttpModule,它只用来处理 Bundle的连接地址,虽然它在HTTP的管道中;找到它就好顺藤摸瓜了,但是奇怪的是我在Web.config里没有发现它的配置信息,奇怪了,难道它还跑去系统文件改,当然是不可能的;所以我一时还想不起能有什么办法动态注册,提起动态注册突然有了思路,好像有一个Assembly级别的特性用来注册Application_Start启动时候的前置代码,会在Application启动之前执行,来看一下;
果然藏着这里呢,它注册了一个PreApplicationStartCode静态类,使用Start方法启动;
这段代码很简单,先判断有没有执行过注册,如果没有就执行动态注册,这个动态注册组件是.NETFramework自带的,在Microsoft.Web.Infrastructure里面只不过属于平台相关的,跟ASP.NET没有直接关系,我们可以用Microsoft.Web.Infrastructure来开发自己的WEB组件;这里有一个疑问,为什么静态方法也要加判断呢,不是只会执行一次吗,因为静态方法的执行是不受控制的,所以如果不加判断很有可能会注册多次,出于严谨考虑还是加上;
现在基本上我们已经找到源头了,服务端这里我们先放一下,对于客户端的疑问很多,它既然帮我们捆绑了,那么缓存是如何处理的,也就是说它的输出缓存有没有设置,如果设置了不是有问题;
【客户端缓存相关】
为了很好的了解请求之间的信息,我们用Fiddler监听一下;
我们看见它的Cache部分是用了If-Modified-Since来表示本地的文件的最后一次修改,这样是为了能够让服务器去验证文件是否改动,如果没有改动服务器的响应状态码为304,说明Bundle在输出的时候并没有设置对这个文件进行客户端强制缓存,我们通过Pragma: no-cache头也能看出来了;
那么我们得出结论,所有Bundle出来的文件都不可能直接缓存在浏览器中,每次都会带上Cache段If-Modified-Since去验证服务器的文件版本;刚好这里我们可以跟动态输出的静态文件地址的后面的参数对上了;
比如:
/Content/css?v=ZPnWVRT3c0yyrVDPmI-xkJuhBdJfQsL3A0K5C9WTOk01
这个链接后面的v参数是表示当前Bundle后虚拟文件的版本,如果我们在服务器上把文件修改了之后那么这个文件的If-Modified-Since验证就失败了,会生成新的版本号作为连接的参数;我们来看一下,心里踏实;
我加了一个width:auto的style,那么这个时候我刷新客户端应该是不会再有304出现了;
显然/Content/css?v=doYFOk3BdOYWDIRbQ7juV6eQdlJAu6RtC0G13El7X041 文件的版本变了,那么Response也不应该是304了;
如果静态文件的版本号发生改变,根本就不会带上 If-Modified-Since,这个是用在每次进行进行Post是用来验证的;其实意思就是说如果没有IIS集成模式那么捆绑文件的方式只能改变静态文件的文件名;
4】扩展自定义类型静态文件
Bundle对象是所有需要捆绑文件的基类,如果我们需要扩展一些静态文件,如一些特定领域的静态文件,我们可以直接继承这个类;
【XML文件的缓存】
扩展XML文件很简单,我们只需要继承一下Bundle对象,所有关于动态生成URL都有专门的对象处理,我们来看下代码;
public class XmlBundle : Bundle
{
public XmlBundle(string path) : base(path) { }
}
public static class XmlBundleRender
{
public static IHtmlString Render(string path)
{
BundleResolver bundle = new BundleResolver(BundleTable.Bundles);
return new HtmlString(
string.Format(@"<link href=""{0}"" rel=""stylesheet""/>", bundle.GetBundleUrl(path)));
}
}
首先我们需要一个继承自Bundle对象的XmlBundle,用来表示我们所有将要传输的XML文件捆绑容器,然后我们需要一个静态方法用来注册捆绑后的URL;
这个URL的生成有专门的BundleResolver对象来完成,我们只需要传入所有的BundleCollection对象,我这里为了能在浏览器中测试所以写了一段stylesheet类型的link;这样我们就能直接在我们需要的地方直接使用了,我在index视图中引用:@MvcApplication4.Seed.XmlBundleRender.Render("~/custom/xml");是不是很简单,这样我们就能对所有想控制捆绑的文件进行捆绑,只需要继承加简单的静态方法辅助;
我们来看一下我们的XML文件是否具有所有缓存特性;
第一次请求没有加If-Modified-Since段,返回的内容是一个简单的<model>222</model> 测试简单,现在我们看它是否在下一次不改变内容的情况下使用缓存;
在我们预料之中,使用了缓存数据,下面我们需要把服务器上的XML文件进行修改,将222改成243454637看是否自动刷新本地缓存也就是说不会是304返回状态;
也刷新缓存,符合理论根据,正确的返回了我们修改后的值;
结:其实HTTP不仅仅用在浏览器中,会有很多使用HTTP的场合,所以我们能很好的将这种功能用来捆绑一些图片、文字等多种场合中,确实是个不错的组件;文章结束,谢谢;
作者:王清培
出处:http://blog.csdn.net/wangqingpei557
本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
ASP.NET 4.5 Bundle组件(捆绑、缩小静态文件)的更多相关文章
-
.NET/ASP.NET 4.5 Bundle组件(捆绑、缩小静态文件)
阅读目录: 1.开篇介绍 2.System.Web.Optimization 组件 3.System.Web.Optimization 组件基本原理 4.扩展自定义类型静态文件 1]开篇介绍 这篇文章 ...
-
asp.net mvc 应用Bundle(捆绑和微小)压缩技术 启用 BundleConfig 配置web.config
从MVC4开始,我们就发现,项目中对Global.asax进行了优化,将原来在MVC3中使用的代码移到了 [App_Start]文件夹下,而Global.asax只负责初始化.其中的BundleCon ...
-
ASP.NET Core 2.2 基础知识(三) 静态文件
什么是静态文件? HTML,CSS,JS,图片等都叫做静态文件. 要想提供静态文件给客户端,需要注册静态文件中间件. 我们先分别添加一个 WebAPI 项目,一个 Razor 视图项目,比较两个项目的 ...
-
Asp.Net Core 中的静态文件
Asp.Net Core 中的静态文件 在这节中我们将讨论如何使 ASP.NET Core 应用程序,支持静态文件,如 HTML,图像,CSS 和 JavaScript 文件. 静态文件 默认情况下, ...
-
15.ASP.NET Core 应用程序中的静态文件中间件
在这篇文章中,我将向大家介绍,如何使用中间件组件来处理静态文件.这篇文章中,我们讨论下面几个问题: 在ASP.NET Core中,我们需要把静态文件存放在哪里? 在ASP.NET Core中 wwwr ...
-
[Asp.net Mvc]通过UrlHelper扩展为js,css静态文件添加版本号
写在前面 在app中嵌入h5应用,最头疼的就是缓存的问题,比如你修改了一个样式,或者在js中添加了一个方法,发布之后,并没有更新,加载的仍是缓存里面的内容.这个时候就需要清理缓存才能解决.但又不想让w ...
-
ASP.NET Core 2.1 : 十四.静态文件与访问授权、防盗链
我的网站的图片不想被公开浏览.下载.盗链怎么办?本文主要通过解读一下ASP.NET Core对于静态文件的处理方式的相关源码,来看一下为什么是wwwroot文件夹,如何修改或新增一个静态文件夹,为什么 ...
-
ASP.NET Core静态文件中间件[1]: 搭建文件服务器
虽然ASP.NET Core是一款"动态"的Web服务端框架,但是由它接收并处理的大部分是针对静态文件的请求,最常见的是开发Web站点使用的3种静态文件(JavaScript脚本. ...
-
ASP.NET MVC下Bundle的使用
ASP.NET MVC中Bundle是用于打包捆绑资源的(一般是css和js),它是在全局文件Global.asax.cs中注册Bundle,而注册的具体实现默认是在App_Start文件夹的Bund ...
随机推荐
-
ASP.NET MVC5 网站开发实践(二) Member区域 - 文章管理架构
上次把member的用户部分完成,现在开始做文章管理部分.文章部分根据涉及显示现实文章列表,发布文章,修改文章,删除文章等功能.最终的实现目标是使用权限来控制用户是否能进行相应操作,管理员权限的会显示 ...
-
Map工具系列-01-Map代码生成工具说明
所有cs端工具集成了一个工具面板 -打开(IE) Map工具系列-01-Map代码生成工具说明 Map工具系列-02-数据迁移工具使用说明 Map工具系列-03-代码生成BySQl工具使用说明 Map ...
-
ADB server didn&#39;t ACK
当我们通过eclipse开发Android应用时,会连接真机会使用模拟器进行仿真,有时候启动失败,会提示这样的错误. 工具/原料 Eclipse CMD命令窗口 方法/步骤 首先通过CMD启动adb服 ...
-
kvm 简介
1. 基础概念 1.1 kvm整合入linux 内核: 1.2 kvm模型中,每一个虚拟机对于linux而言都是一个标准进程: 1.3 普通的linux进程有用户和内核两个空间,在kvm模型中定义了客 ...
-
JS中offsetLeft,Left,clientLeft的区别(纯转贴)
假设 obj 为某个 HTML 控件. obj.offsetTop 指 obj 相对于版面或由 offsetParent 属性指定的父坐标的计算上侧位置,整型,单位像素. obj.offsetLeft ...
-
Sync FrameWork 文件同步 (源码)
Sync Framework 是一个功能完善的同步平台,实现了应用程序.服务和设备的协作和脱机访问.Sync Framework 提供了一些可支持在脱机状态下漫游.共享数据和获取数据的技术 和工具.通 ...
-
JavaScript对象应用-字符串和图片对象
1.1 应用 String对象截取特定文字 利用String 对象的charAt() 和 substring() 方法等,截取特定文字或字段文字显示在页面上 <html> <he ...
-
【转】qlv文件如何转换成mp4 怎样把下载好的qlv格式视频转换成MP4格式
狸窝 复制 收藏 保存到桌面 快速找教程方案 反馈需求 *核心价值观 客服QQ41442901 马上注册 升级VIP 对于视频文件之间的转换问题,我也已经是无力吐槽了,每个 ...
-
RSS简介
1.RSS(Really Simple Syndication)简介 1.定义 对于网站:RSS 是一种使用 XML 向许多其他的网站分发自己网站上的网络内容的方法. 对于用户:RSS ...
-
5. React 组件的协同使用 组件嵌套和Mixin
组件是React的核心,构建大型项目时多个组件之间需要进行协同使用.可以从横向和纵向两个角度来实现组件的协同使用,纵向的协同使用就是组件嵌套,横向的协同使用就是Mixin(抽取公共方法 ...