ASP.NET Core 中的响应缓存中间件
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了ASP.NET Core 中的响应缓存中间件,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4891字,纯文字阅读大概需要7分钟。
内容图文
客户端(浏览器)缓存
通过设置HTTP的响应头来完成
1、直接用Response对象去设置
[HttpGet] public IEnumerable<WeatherForecast> Get() { Console.WriteLine("服务响应"); //直接一,简单粗暴,不要拼写错了就好~~ Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.CacheControl] = "public, max-age=600"; var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); }View Code
查看http响应头
上面的示例设置客户端缓存600秒,如果直接刷新浏览器或者按F5进行刷新,缓存会失效(cache-control对刷新无效)
2、用ResponseCacheAttribute类设置缓存
[HttpGet] [ResponseCache(Duration = 100)] public IEnumerable<WeatherForecast> Get() { Console.WriteLine("服务响应"); ////直接一,简单粗暴,不要拼写错了就好~~ //Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.CacheControl] = "public, max-age=600"; var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); }View Code
效果和上面是一致的,通过源码分析发现ResponseCacheAttribute也是通过设置http头来实现的。
/// <summary> /// Specifies the parameters necessary for setting appropriate headers in response caching. /// </summary> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class ResponseCacheAttribute : Attribute, IFilterFactory, IOrderedFilter { /// <inheritdoc /> public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>(); var optionsAccessor = serviceProvider.GetRequiredService<IOptions<MvcOptions>>(); var cacheProfile = GetCacheProfile(optionsAccessor.Value); // ResponseCacheFilter cannot take any null values. Hence, if there are any null values, // the properties convert them to their defaults and are passed on. return new ResponseCacheFilter(cacheProfile, loggerFactory); } }View Code
ResponseCacheFilter部分代码如下
/// <summary> /// An <see cref="IActionFilter"/> which sets the appropriate headers related to response caching. /// </summary> internal class ResponseCacheFilter : IActionFilter, IResponseCacheFilter { /// <inheritdoc /> public void OnActionExecuting(ActionExecutingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // If there are more filters which can override the values written by this filter, // then skip execution of this filter. var effectivePolicy = context.FindEffectivePolicy<IResponseCacheFilter>(); if (effectivePolicy != null && effectivePolicy != this) { _logger.NotMostEffectiveFilter(GetType(), effectivePolicy.GetType(), typeof(IResponseCacheFilter)); return; } _executor.Execute(context); } }View Code
具体的实现是在ResponseCacheFilterExecutor类中,代码如下
internal class ResponseCacheFilterExecutor { public void Execute(FilterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (!NoStore) { // Duration MUST be set (either in the cache profile or in this filter) unless NoStore is true. if (_cacheProfile.Duration == null && _cacheDuration == null) { throw new InvalidOperationException( Resources.FormatResponseCache_SpecifyDuration(nameof(NoStore), nameof(Duration))); } } var headers = context.HttpContext.Response.Headers; // Clear all headers headers.Remove(HeaderNames.Vary); headers.Remove(HeaderNames.CacheControl); headers.Remove(HeaderNames.Pragma); if (!string.IsNullOrEmpty(VaryByHeader)) { headers[HeaderNames.Vary] = VaryByHeader; } if (VaryByQueryKeys != null) { var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>(); if (responseCachingFeature == null) { throw new InvalidOperationException( Resources.FormatVaryByQueryKeys_Requires_ResponseCachingMiddleware(nameof(VaryByQueryKeys))); } responseCachingFeature.VaryByQueryKeys = VaryByQueryKeys; } if (NoStore) { headers[HeaderNames.CacheControl] = "no-store"; // Cache-control: no-store, no-cache is valid. if (Location == ResponseCacheLocation.None) { headers.AppendCommaSeparatedValues(HeaderNames.CacheControl, "no-cache"); headers[HeaderNames.Pragma] = "no-cache"; } } else { string cacheControlValue; switch (Location) { case ResponseCacheLocation.Any: cacheControlValue = "public,"; break; case ResponseCacheLocation.Client: cacheControlValue = "private,"; break; case ResponseCacheLocation.None: cacheControlValue = "no-cache,"; headers[HeaderNames.Pragma] = "no-cache"; break; default: cacheControlValue = null; break; } cacheControlValue = $"{cacheControlValue}max-age={Duration}"; headers[HeaderNames.CacheControl] = cacheControlValue; } } }View Code
通过源码分析已经知道了ResponseCacheAttribute运作的基本原理,下面再来看看如何配置出其他不同的效果。
内容总结
以上是互联网集市为您收集整理的ASP.NET Core 中的响应缓存中间件全部内容,希望文章能够帮你解决ASP.NET Core 中的响应缓存中间件所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。