如何正确实现多版本页面缓存?三类控制器方法的缓存配置方案
ASP.NET MVC 三类控制器方法OutputCache配置方案
1. 分类列表片段缓存(KatList子操作方法)
该方法是[ChildActionOnly]标注的子操作,属于片段缓存,用于输出侧边栏分类列表,配置规则如下:
- 方法本身无入参,
VaryByParam直接设置为none即可,原注释中的*不会产生额外作用,反而会增加不必要的参数校验逻辑 - 若分类列表是全站统一、无用户个性化内容,不需要额外加
VaryByHeader配置;如果分类会根据登录用户权限展示不同内容,需要新增VaryByCustom="user"来按用户标识区分缓存 - 缓存时长可根据分类更新频率调整,若分类很少变动可从默认20秒拉长到600秒(10分钟),减少服务器压力
最终配置参考:
[ChildActionOnly] [OutputCache(Duration = 600, VaryByParam = "none")] // 若存在用户个性化分类则使用下面的配置 // [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "user")] public ActionResult KatList() { return PartialView(KatModelFactory.NewKatModel(Ctx, Session, false)); }
2. 搜索接口缓存(Search Post方法)
该方法是接收搜索请求的Post方法,返回搜索结果,配置规则如下:
- 不要直接用
VaryByParam="*",建议明确指定搜索相关的参数名,比如HeaderModel里的Keyword、SortType、FilterId等搜索字段,用分号分隔,避免无关参数生成冗余缓存 - 如果站点有PC/移动端两套搜索结果展示,新增
VaryByHeader="User-Agent"按客户端类型区分缓存;有多语言站点则加VaryByHeader="Accept-Language" - 若搜索结果会根据用户权限做内容过滤,需加
VaryByCustom="user"按用户区分缓存 - 注意Post请求缓存仅在相同请求参数重复提交时生效,不会被浏览器端缓存,仅缓存在服务器端
最终配置参考(假设搜索参数为Keyword、CategoryId、Sort):
[HttpPost] [OutputCache(CacheProfile = "Cache30Min", VaryByParam = "Keyword;CategoryId;Sort", VaryByHeader = "User-Agent;Accept-Language")] // 有权限过滤要求则加VaryByCustom="user" // [OutputCache(CacheProfile = "Cache30Min", VaryByParam = "Keyword;CategoryId;Sort", VaryByHeader = "User-Agent;Accept-Language", VaryByCustom = "user")] public ActionResult Search(HeaderModel model) { //omitted }
3. 分类详情页缓存(Category Get方法)
该方法是返回页面主体的Get方法,入参只有分类id,配置规则如下:
VaryByParam直接指定为id即可,比*更高效,避免URL上的无关查询参数生成多余缓存- 同样如果有PC/移动端差异、多语言需求,新增对应的
VaryByHeader配置 - 若页面有用户个性化内容(比如登录后显示已收藏标识),加
VaryByCustom="user"
最终配置参考:
[HttpGet] [OutputCache(CacheProfile = "Cache30Min", VaryByParam = "id", VaryByHeader = "User-Agent;Accept-Language")] // 有个性化内容则加VaryByCustom="user" // [OutputCache(CacheProfile = "Cache30Min", VaryByParam = "id", VaryByHeader = "User-Agent;Accept-Language", VaryByCustom = "user")] public ActionResult Category(string id) { return View(KatModelFactory.NewKatModelDetail(Ctx, Session, id)); }
通用补充说明
- 如果需要按Session区分缓存,需要在Global.asax里重写
GetVaryByCustomString方法,返回对应用户标识或者SessionId即可 - 所有缓存时长可根据业务内容的更新频率灵活调整,内容更新频繁就缩短时间,也可以配合缓存依赖在数据更新时主动清空对应缓存
内容的提问来源于stack exchange,提问作者nurmanbetov
相关产品推荐
相关产品推荐

