• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >ASP.NET > ASP.NET组件System.Web.Optimization原理及缓存问题详解

ASP.NET组件System.Web.Optimization原理及缓存问题详解

作者:王清培 字体:[增加 减小] 来源:互联网 时间:2017-05-11

王清培通过本文主要向大家介绍了asp.net,asp net培训,asp和asp.net的区别,零基础学asp.net,c#和asp.net的区别等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

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)));
 }
 }

</div>

首先我们需要一个继承自Bundle对象的XmlBundle,用来表示我们所有将要传输的XML文件捆绑容器,然后我们需要一个静态方法用来注册捆绑后的URL;

这个URL的生成有专门的BundleResolver对象来完成,我们只需要传入所有的BundleCollection对象,我这里为了能在浏览器中测试所以写了一段stylesheet类型的link;这样我们就能直接在我们需要的地方直接使用了,我在index视图中引用:@MvcApplication4.Seed.XmlBundleRender.Render("~/custom/xml");是不是很简单,这样我们就能对所有想控制捆绑的文件进行捆绑,只需要继承加简单的静态方法辅助;

我们来看一下我们的XML文件是否具有所有缓存特性;

第一次请求没有加If-Modified-Since段,返回的内容是一个简单的<model>222</model> 测试简单,现在我们看它是否在下一次不改变内容的情况下使用缓存;

在我们预料之中,使用了缓存数据,下面

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Asp.net SignalR 应用并实现群聊功能 开源代码
  • asp.net动态更新
  • asp.net利用母版制作页脚效果
  • Asp.Net服务器发送HTTP标头后无法设置内容类型的问题解决
  • 使用asp.net mvc,boostrap及knockout.js开发微信自定义菜单编辑工具(推荐)
  • 详解ASP.NET MVC 常用扩展点:过滤器、模型绑定
  • ASP.NET Core发送邮件的方法
  • 在ASP.NET Core 中发送邮件的实现方法(必看篇)
  • ASP.NET MVC从视图传参到控制器的几种形式
  • Asp.net core WebApi 使用Swagger生成帮助页实例

相关文章

  • 2017-05-11.net使用自定义类属性实例
  • 2017-05-11.NET的Ajax请求数据提交实例
  • 2017-05-11asp.net 字符串、二进制、编码数组转换函数
  • 2017-05-11VS2015 搭建Asp.net core开发环境的方法
  • 2017-05-11.net后台代码调用前台JS的两种方式
  • 2017-05-11把aspx页面伪装成静态html格式的实现代码
  • 2017-05-11实例讲解动态加载gridview中的行及其样式
  • 2017-05-11正则方式的自动小偷抓网程序
  • 2017-05-11ASP.NET 程序优化 小结
  • 2017-05-11ASP.NET设计网络硬盘之两重要类代码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Asp.net,C# 加密解密字符串的使用详解
    • 获取DataRow[]的值示例
    • ASP.NET DropDownListCheckBox使用示例(解决回发问题)
    • 使用pdfbox实现pdf文本提取和合并功能示例
    • 详解asp.net core封装layui组件示例分享
    • 向asp.Net进发 数据库连接操作
    • ASP.NET数据库存取图片的方法
    • 详解免费高效实用的.NET操作Excel组件NPOI(.NET组件介绍之六)
    • .NET中StringBuilder用法实例分析
    • ABP框架的基础配置及依赖注入讲解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有