HTTP响应的缓存意味着当发出HTTP请求时,服务器生成的响应由浏览器或服务器存储在某个地方,以便在对同一资源的连续HTTP请求中重复使用。实质上,我们正在存储生成的响应,并将该响应重用于后续请求一段时间。存储可以在客户端进行,例如浏览器或服务器端本身。当存储在客户端时,HTTP响应的缓存减少了客户端(例如浏览器或代理)对Web服务器的请求数。Web应用程序中的浏览器缓存行为通常由指定客户端必须如何缓存响应的HTTP报头控制。
在Web应用程序中,需要缓存某些性能请求。例如,通过缓存很少更改或不经常更改的资源来提高应用程序的性能,因为这会从服务器中删除不必要的工作。另一方面,可能不会缓存某些可能经常更改的资源,以便向客户端提供最新资源。因此,需要缓存某些资源并禁止缓存某些其他资源。
在典型的HTTP请求和响应中,缓存由“Cache-Control” 报头控制。报头可以告诉缓存什么以及客户端和服务器的时间长度。在.NET Core MVC中,可以指定缓存使用ResponseCache属性。
向操作方法添加缓存行为的一种简单方法是使用ResponseCache特性来修饰方法。为了使客户端缓存响应,可以使用[ResponseCache(Duration = 30)] 修饰控制器内的操作方法。此特性将标记客户端以响应缓存30秒。可以通过使用[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]特性来禁用响应的缓存,其中NoStore标志设置为true,CachingLocation设置为None。
下面的示例显示来自Index()和Privacy()方法的响应被缓存30秒。我们的想法是,这些方法生成的内容预计会保持不变。GetValue()方法的响应不应该缓存,因为预期此方法的响应会从一个请求更改为另一个请求。因此,禁用缓存由NoStore = true和Location = ResponseCacheLocation.None指示。
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace Web.Controllers { public class HomeController : Controller { [ResponseCache(Duration = 30)] public IActionResult Index() { return View(); } [ResponseCache(Duration = 30)] public IActionResult Privacy() { return View(); } [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult GetValue() { return View(); } } }
为了对类的所有操作方法使用相同的缓存行为,[ResponseCache]可以在类级别对该属性进行修饰。例如,在下面的代码中,每个操作方法的响应将被缓存30秒。
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace Web.Controllers { [ResponseCache(Duration = 30)] public class HomeController : Controller { public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } public IActionResult GetValue() { return View(); } } }
还可以覆盖一个或多个方法的缓存行为。例如,在下面的代码中,类级别缓存行为是允许缓存响应30秒,但通过使用[ResponseCache] 装饰单个方法进行,可以更改方法响应的缓存。在这种情况下,GetValue()的响应永远不会被缓存,因为 [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]。
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace Web.Controllers { [ResponseCache(Duration = 30)] public class HomeController : Controller { public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult GetValue() { return View(); } } }
在上面的示例中,有两个主要的缓存行为,一个表示缓存,另一个表示无缓存。参数ResponseCachelocation,NoStore和Duration可以放入一个配置文件,并在.NET Core MVC中使用和重用这些属性。让我们假设应用程序中有一些缓存行为类型如下:
- 默认——每个响应都缓存60秒
- 从不——没有缓存任何响应。
可以将这两种行为转换为缓存配置文件。ResponseCache可以在如下所示的ConfigureServices(IServiceCollection服务)方法中的MVC中间件的StartUp.cs文件中设置:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace Web { public class Startup { //.... // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc(options => { options.CacheProfiles.Add("Default", new CacheProfile() { Duration = 60 }); options.CacheProfiles.Add("Never", new CacheProfile() { Location = ResponseCacheLocation.None, NoStore = true }); }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } ///.... } }
在上面的代码中,两个缓存配置文件分别配置为“默认”和“从不”。“默认”缓存配置文件旨在将响应缓存60秒,如以下行所示:
{ Duration = 60 }
“从不”缓存配置文件旨在请求在以下情况下指定不应发生响应缓存:
{ Location = ResponseCacheLocation.None, NoStore = true }
现在缓存配置文件是在MVC上设置的,它们的操作方法可以通过指定配置文件的名称而不是通过提供缓存相关参数来开始使用它。例如,为了允许缓存,特性是[ResponseCache(CacheProfileName = "Default")]和不允许缓存,特性是 [ResponseCache(CacheProfileName = "Never")]。上面例子中的HomeController类,现在可以通过在HomeController类上使用装饰[ResponseCache(CacheProfileName = "Default")]和使用[ResponseCache(CacheProfileName = "Never")]特性的GetValue()方法来修改。
using Microsoft.AspNetCore.Mvc; namespace Web.Controllers { [ResponseCache(CacheProfileName = "Default")] public class HomeController : Controller { public HomeController() { } public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } [ResponseCache(CacheProfileName = "Never")] public IActionResult GetValue() { return View(); } } }
通过上述更改,home控制器内的所有方法将开始使用“默认”缓存配置文件,该配置文件基本上将缓存响应60秒。
在HomeController中我们有两个get方法。第一种方法是Index()返回产品列表,另一种方法Privacy()返回带有隐私相关内容的视图,最后GetValue()返回第三种方法,返回一些值。在这种情况下,我们还假设产品类型相对稳定,即它们的数据不会经常变化。但是,产品会根据库存而不断变化,因此不适合缓存。因为,如果我们在数据库中缓存产品和产品库存增加或减少,那么缓存的响应将是不正确的。
我们可以通过执行以下操作来验证缓存是否正常:
- 在本地运行应用程序并转到index方法。
- 打开PostMan或ARC以获取请求并查看响应标头。响应标头表示已使用缓存。
- 现在注释掉相关的回复。
- 在PostMan中重新创建请求并查看响应报头。
资源:
ASP.NET Core中的响应缓存。可在以下链接中获得:
Response caching in ASP.NET Core
英文原文地址:
https://www.codeproject.com/Articles/1280493/Handling-Caching-with-ResponseCache-attribute-in-t