一、ASP.NET MVC中使用OutputCache实现服务器端页面级缓存

在ASP.NET MVC中,假如我们想要将某个页面(即某个Action)缓存在服务器端,可以在Action上标上以下特性:

1 [OutputCache(Duration = 10, VaryByParam = "*", Location = OutputCacheLocation.Server)]
2 public ActionResult Login()
3 {
4 ViewBag.Message = "Your app description page. " + DateTime.Now.ToString();
5 LoginModel loginModel = new LoginModel();
6 ViewBag.IsValCodeVisible = IsValCodeVisible();
7 return View(new LoginModel());
8 }

想要使OutputCache这个特性生效,还需以下几个条件:

1、Action必须是[HttpGet]。

2、Web.Config中设置<system.web>/<compilation debug="false">,即应用程序的编译条件不能是Debug。

3、页面响应Response中不能有Cookies。

  • 1)在.NET Framework 2.0.50727.4209以前,包含Cookies的页面响应可以输出缓存,源码如下:

  • 2)从.NET Framework 2.0.50727.4209开始,加入了对Cookies的判断,如果页面响应中包含Cookies,则不输出缓存,而是重新执行代码。

ASP.NET MVC 4基于.NET Framework 4或者4.5,所以同样对Cookies作了判断,这意味着如果Forms身份验证的Cookie输出方式为HttpOnly,

那么经过验证的页面不会输出页面缓存,因为每一次响应中都会带有身份验证票加密后生成的Cookie。

二、为什么说尽量不要重写AuthorizeAttribute的OnAuthorization()方法?

AuthorizeAttribute的源码中的OnAuthorization()方法有这样的注释:

// Since we're performing authorization at the action level, the //authorization code runs
// after the output caching module. In the worst case this could allow //an authorized user
// to cause the page to be cached, then an unauthorized user would //later be served the
// cached page. We work around this by telling proxies not to cache the //sensitive page,
// then we hook our custom authorization code into the caching //mechanism so that we have
// the final say on whether a page should be served from the cache.

大意是说这个方法中处理了服务器端页面缓存问题,保证每个未验证的用户都需经过验证,而不是直接读取服务器端页面缓存。那么什么场景下会出现缓存问题,以及这个缓存问题的具体表现是什么呢?下面就来演示一下。

1、新建ASP.NET MVC 4 Web应用程序,“项目模板”选择“Internet应用程序”。

2、自定义一个继承至"AuthorizeAtrribute"的类,这个类重写了OnAuthorization(),并且没有针对OutputCache进行处理。

 1 public class CustomAuthorizeAttribute : AuthorizeAttribute
2 {
3 public override void OnAuthorization(AuthorizationContext filterContext)
4 {
5 if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
6 {
7 HandleUnauthorizedRequest(filterContext);
8 }
9 }
10 }

3、找到Controllers/HomeController/Index,标注以下特性。

1 [HttpGet]
2 [CustomAuthorize]
3 [OutputCache(Duration = 30, Location = OutputCacheLocation.Server, VaryByParam = "*")]
4 public ActionResult Index()
5 {
6 ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。";
7 return View();
8 }

4、经过以上3个步骤后,按照预期,一个用户访问完Home/Index后,Home/Index这个页面会在服务器端缓存起来(Location = OutputCacheLocation.Server),后续的另一个用户访问Home/Index,则会直接读取页面缓存,而不需要重新执行Home/Index的代码(当然也包括身份验证等特性的代码)。为了模拟两个不同的用户,下面选择Chrome和IE两个不同的浏览器访问页面。

首先打开Chrome浏览器,访问Account/Login,输入账号密码进行登录,然后访问首页Home/Index,显示如下:

接着打开IE浏览器,直接访问Home/Index。如果没有页面缓存,这时候是不能直接打开页面的,因为Home/Index已经标注了[CustomAuthorize],是需要身份验证的,但因为有了页面缓存,所以服务器直接将第一次在Chrome浏览器访问Home/Index时在服务器留下的缓存发送给IE浏览器的请求。页面显示如下:

ASP.NET保存Cookie的方式默认不是HttpOnly,不会在每次页面响应中带有Cookie,服务器端的OutputCache可以生效,所以这种情况下重写AuthorizeAttribute的OnAuthorization()就会有问题。

在ASP.NET MVC 3 中自定义AuthorizeAttribute时需要注意的页面缓存问题的更多相关文章

  1. [转]在 ASP.NET MVC 4 中创建为移动设备优化的视图

    原文链接 https://msdn.microsoft.com/zh-cn/magazine/dn296507.aspx 如果深入探讨有关编写移动设备网站的常识性考虑因素,会发现其中有一种内在矛盾.  ...

  2. ASP.NET MVC 4中如何为不同的浏览器自适应布局和视图

    在ASP.NET MVC 4中,可以很简单地实现针对不同的浏览器自适应布局和视图.这个得归功于MVC中的"约定甚于配置"的设计理念. 默认的自适应 MVC 4自动地为移动设备浏览器 ...

  3. 在ASP.NET MVC环境中使用加密与解密

    在.NET Framework 4.5的NET框架中,在程序中加密与解密很方便.现在均学习ASP.NET MVC程序了,因此Insus.NET也在此写个学习的例子.在需要时可以参考与查阅. 写一个Ut ...

  4. ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

    ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需 要将相应的ValidationAttr ...

  5. 在 ASP.NET MVC 项目中使用 WebForm、 HTML

    原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各 ...

  6. asp.net mvc Route 使用自定义条件(constraints)禁止某ip登陆

    asp.net mvc Route 使用自定义条件(constraints)禁止某ip登陆 前言 本文的目的是利用Mvc route创建一个自定义约束来控制路由跳转实现禁止ip登陆,当然例子可能不合理 ...

  7. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

  8. 在ASP.NET MVC应用中开发插件框架(中英对照)

    [原文] Developing a plugin framework in ASP.NET MVC with medium trust [译文] 在ASP.NET MVC应用中开发一个插件框架 I’v ...

  9. 【初学者指南】在ASP.NET MVC 5中创建GridView

    介绍 在这篇文章中,我们将会学习如何在 ASP.NET MVC 中创建一个 gridview,就像 ASP.NET Web 表单中的 gridview 一样.服务器端和客户端有许多可用的第三方库,这些 ...

随机推荐

  1. 【微信支付】公众号、商户基础配置和流程(包括设置支付授权目录、测试支付目录和白名单、JS接口安全域名、授权回调域名等)

    一.使用场景以及说明 使用场景:商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程. 说明:1.用户打开图文消息或者扫描二维码,在微信内置浏览器打开网 ...

  2. `libsass` bindings not found. Try reinstalling `node-sass`?

    本篇文章由:http://xinpure.com/libsass-bindings-not-found-try-reinstalling-node-sass/ 坑一记 `libsass` bindin ...

  3. js表单验证控制代码大全

    http://www.cnblogs.com/SAL2928/archive/2008/10/24/1319020.html目录: 1:js 字符串长度限制.判断字符长度.js限制输入.限制不能输入. ...

  4. python --subprocess 范例

    范例1:查看ipconfig -all命令的输出,并将将输出保存到文件tmp.log中: import subprocess handle = open(r'd:\tmp.log','w') p=su ...

  5. Ubuntu安装deb软件包错误(依赖关系问题)解决

    执行命令 sudo dpkg -i XXX.deb 返回依赖关系错误提示 执行 sudo apt-get -f install 这条命令将自动安装需要的依赖包. 再次执行命令 sudo dpkg -i ...

  6. 常用音频软件:Cool edit pro

    作者:桂. 时间:2017-06-02  11:51:08 链接:http://www.cnblogs.com/xingshansi/p/6932671.html 这里只涉及Cool edit pro ...

  7. Atitit.mysql oracle with as模式临时表模式 CTE 语句的使用,减少子查询的结构性 mssql sql server..

    Atitit.mysql  oracle with as模式临时表模式 CTE 语句的使用,减少子查询的结构性 mssql sql server.. 1. with ... as (...) 在mys ...

  8. InnoDB存储引擎表的逻辑存储结构

    1.索引组织表:     在InnoDB存储引擎中,表都是依照主键顺序组织存放的.这样的存储方式的表称为索引组织表,在innodb存储引擎表中,每张表都有主键.假设创建的时候没有显式定义主键,则Inn ...

  9. 源码分析:Java堆的创建

    虚拟机在内存中申请一片区域,由虚拟机自动管理,用来满足应用程序对象分配的空间需求,即堆空间. 由于程序运行的局部特性,程序创建的大多数对象都具有非常短的生命周期,而程序也会创建一些生命周期特别长的对象 ...

  10. Struts2使用OGNL遍历各种map总结

    一.Action中的代码:MapAction.java package com.zx.demo.action; import java.util.ArrayList;   import java.ut ...