当前位置: 移动技术网 > IT编程>开发语言>c# > Asp.Net中MVC缓存详解

Asp.Net中MVC缓存详解

2019年07月18日  | 移动技术网IT编程  | 我要评论
本文通过介绍了asp.net中mvc缓存的种类,以及他们之间的区别等内容,让学习者能够深入的了解mvc缓存的原理机制,以下是具体内容: 缓存是一种保存资源副本并在下次请求

本文通过介绍了asp.net中mvc缓存的种类,以及他们之间的区别等内容,让学习者能够深入的了解mvc缓存的原理机制,以下是具体内容:

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝。

web应用缓存技术大体上可以分为两类:服务端缓存和客户端缓存。两种目标都是减少重复性内容的生成和网络传输工作,因为缓存数据存储的位置不同,而分为服务端缓存和客户端缓存。

服务端缓存

服务端缓存技术关注于服务端数据查询,生成或者操作技术。主要就是减少处理请求的工作量,减少数据库查询次数和生成html数据的cpu周期--减少每个bit的数据。
对于服务端缓存来说,不管是刷新页面,重新输入地址,还是control+f5都不会规避缓存,如果缓存数据有效,一定是请求的缓存数据。

输出缓存(output cache)

输出缓存是asp.net下最常用的缓存机制。输出缓存,缓存服务端生成的html数据--缓存action下返回数据(html/json)。这样,在每次调用相同的action时,就不需要再次执行action方法。

缓存位置(location)

outputcache使缓存的内容一般放在三个位置上:服务端,代理服务器,浏览器客户端。通过loaction属性可以设置缓存的位置。

loaction属性有如下值:

any client downstream server none serverandclient

默认值为any,就是在三个位置都会缓存。但是应该根据不同的情况使用不同的缓存位置。比如:要缓存的内容是针对特定用户的,每个用户都会不同。这样的话,该缓存就不能保存在服务器上。应该保存在浏览器客户端上。

使用output cache

controller或者action上添加[outputcache]特性,使得被添加的controlleraction可以缓存返回的数据。(在action添加会缓存当前的action,在controller会缓存该controller下的所有action)

如下代码:当第一次方法该action时,开始计时10秒,此10秒内所有访问该action的请求都会请求缓存数据。当10秒结束后,再重新开始等待新一次请求,开始新的10秒缓存。就是每隔10秒丢掉旧缓存,等待新的请求,更新缓存数据。

using system.web.mvc;
using system.web.ui;
namespace mvcapplication1.controllers
{
 public class homecontroller : controller
 {
  //缓存时间10秒,缓存变量为无,缓存位置为服务端
  [outputcache(duration=10, varybyparam="none", location = outputcachelocation.server)]
  public actionresult index()
  {
   return view();
  }
 }
}

view:

@{
 viewbag.title = "index";
}
<h2>index</h2>
<p>@datetime.now.tostring()</p>

点击f12,查看请求

需要注意的是:

该缓存时间是绝对时间。此缓存是对所有访问该页面的用户都有效。不能保证缓存一定有效。当内存资源不够时,缓存就会自动地将没用的或者优先级低缓存清除。

客户端缓存

除了服务端缓存外,客户端也可以缓存数据。它避免了向服务器重复提交获取重复数据的请求,把一些重复数据缓存到本地。服务端缓存是为了更快的处理客户端请求,而客户端缓存则是为了避免不必要的请求。

(浏览器会自动把静态资源缓存到浏览器)

mvc中指定location值为outputcachelocation.client 使缓存在浏览器客户端上。

using system.web.mvc;
using system.web.ui;
namespace mvcapplication1.controllers
{
 public class badusercontroller : controller
 {
  //缓存时间为10秒,缓存参数为无,缓存位置为客户端
  [outputcache(duration = 10, varybyparam = "none",location = outputcachelocation.client)]
  public actionresult clientcache()
  {
   return view();
  }
 }
}

@{
 viewbag.title = "clientcache";
}
<h2>clientcache</h2>
<p>@datetime.now.tostring()</p>

客户端缓存和服务端缓存不一样。

刷新,重新输入地址,和control+f5都有可能破坏客户端缓存,从服务端重新获取数据。
浏览器刷新,和重新输入地址会避免请求该url页面的客户端缓存,只避免请求该url页面的缓存。(如果该页面有其他url是被客户端缓存的,这些资源或页面的缓存不会被避免)。

那么什么情况下客户端缓存才有效?

通过url访问,客户端缓存才有效。

比如:

页面a是客户端缓存,同时页面a有一个跳向页面b的链接。通过a到达页面b,同时页面b也有一个链接,这个链接跳向a。通过b再次访问a,此时页面a获取的数据就是客户端的缓存数据,并没有请求服务端,是没有请求服务端。不是304,status-code依然是200。 status-code:304/200(from cache)

304

只有当客户端和服务端同时都缓存了数据。且缓存没有更新的时候,才会有304。即这个缓存是要到服务端验证(根据etag和if-modify-since),该缓存是否最新。如果要更新缓存,从服务端获取数据,status code:200,否则status code:304.

304 和200(from cache)区别

304是会到服务端去校验一次当前客户端缓存是否有效(根据etag和if-modify-since)。而200(from cache)则没有向服务端校验,也没有向服务端请求,直接使用了客户端缓存。

有时我们又需要避免这种没有向服务端请求,直接使用缓存的情况。解决办法就是更改这个缓存的url,添加一个版本号或唯一值。这样因为url的更改使得在客户端没有对应的url缓存,就会从服务端重新获取,再缓存该url的数据。

不同内容的输出缓存

之前的缓存都是action返回相同的内容。如果action每次返回的内容不同,那又该怎么缓存这些不同的内容呢?

使用outputcache特性的varybyparam属性来解决这个问题。当表单参数或查询字符串参数变化时,该属性能够创建同一个action下不同的缓存。

如下代码:master 获取列表。details 获取列表中选择项的详细内容。通过使用varybyparam来缓存不同的id的列表项的详细内容。

using system.web.mvc;
namespace mvcapplication1.controllers
{
 public class moviescontroller : controller
 {
  public moviescontroller()
  {
  }
  [outputcache(duration=int.maxvalue, varybyparam="none")]
  public actionresult master()
  {
   //获取列表
   return view();
  }
  [outputcache(duration = int.maxvalue, varybyparam = "id")]
  public actionresult details(int id)
  {
   //根据参数id,从数据库中获取指定详细内容,并缓存该内容。不同的id会得到不同的内容,自然也会有缓存。
   //但是如果设置varybyparam="none"那么不管id是多少,都直接从缓存中获取数据,不执行该action,这样就会只返回第一次选择项的数据。
   return view();
  }
 }
}

details()操作包括一个带有值“id”的varybyparam属性。当将id参数的不同值传递给控制器操作时,将生成不同的缓存内容。

varybyparam可以根据参数缓存不同的内容

varybyparam="*": 每当表单或查询字符串参数变化时,创建一个不同的缓存版本。当varybyparam="none": 不创建不同的缓存内容,不根据参数缓存不同的内容,即只有一个内容的缓存。当varybyparam="参数列表": 为不同的参数创建不同的缓存版本。

缓存配置

除了在outputcache特性上直接配置缓存策略,可以在web.config文件中使用缓存配置文件,同一管理缓存的策略。使用配置文件相比直接使用属性有如下几点好处:

可以实现一次定义,多处使用。

可以修改web配置文件,而无需重新编译应用程序。(如果想把已经部署到生产环境中的应用程序禁用缓存,可以修改web配置文件中定义的缓存配置。对web配置文件的任何更改都将被自动检测并应用。)

例如,web.config部分定义了一个名为“cache1hour”的缓存配置文件。使用该配置项时,只需指定cacheprofile=配置项名称即可。

<caching>
<outputcachesettings>
 <outputcacheprofiles>
  <add name="cache1hour" duration="3600" varybyparam="none"/>
 </outputcacheprofiles>
</outputcachesettings>
</caching>
using system;
using system.web.mvc;
namespace mvcapplication1.controllers
{
 public class profilecontroller : controller
 {
  //配置文件中的缓存策略名称赋值给cacheprofile
  [outputcache(cacheprofile="cache1hour")]
  public string index()
  {
   return datetime.now.tostring();
  }
 }
}

简单介绍下http缓存的头相关信息:

消息头 类型 说明
expires thu, 30 nov 2017 08:21:14 gmt 响应 过期时间,为格林威治时间 (gmt)
pragma no-cache 响应 忽略浏览器缓存(http1.1用cache-control代替)
cache-control no-cache 请求/响应 客户端缓存验证
cache-control no-store 请求/响应 不在任何地方保存数据,不允许被缓存
cache-control max-age=[秒] 请求/响应 设置浏览器缓存最长时间
cache-control public 响应 缓存在任何地方
cache-control private 响应 缓存该用户的浏览器
last-modified thu, 30 nov 2017 08:21:14 gmt 响应 告诉浏览器服务端最后一次修改的时间
if-modified-since thu, 30 nov 2017 08:21:14 gmt 请求 如果浏览器中last-modofied有值,在请求中把值给if-modified-since,提交给服务端
etag 3df04c15b968d31:0 响应 该资源及其版本在服务端的唯一标识
if-none-match 3df04c15b968d31:0 请求 把上次请求中获取到的etag值,赋值给if-none-match并提交给服务端
vary accept-encoding 响应 从多个缓存副本中选择匹配的版本

有几个容易理解错误的点

no-cache: 使用no-cache 指令的目的是为了防止从缓存中使用过期的资源,所以每次使用缓存时都要到服务端去验证。从字面意思上很容易把no-cache误解成为不缓存,但事实上no-cache代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源。

no-store: 不存储客户端相关请求或服务器响应的任何内容,即真正的不缓存。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网