ASP.NET MVC如何缓存Shared文件夹中Html.Partial输出并配置缓存参数?
你提到控制器方法可以用[OutputCache]特性实现缓存,但直接用@Html.Partial调用的部分视图没法直接加这个特性,不过有两种很实用的方案能搞定,还能灵活配置缓存参数:
方案一:把部分视图包装成子动作(推荐,和控制器缓存逻辑一致)
这种方式最省心,完全复用你熟悉的[OutputCache]特性配置,步骤很简单:
给侧边栏加个控制器子动作
在任意控制器(比如HomeController)里写一个返回这个部分视图的子动作,然后贴上[OutputCache]特性,按需配置参数:public class HomeController : Controller { // 这里配置缓存10分钟,按参数变化缓存,缓存存在服务器端 [OutputCache(Duration = 600, VaryByParam = "*", Location = OutputCacheLocation.Server)] public ActionResult Sidebar() { // 如果侧边栏需要模型数据,就在这里准备(比如从数据库拉取菜单列表) var sidebarModel = GetSidebarMenuData(); return PartialView("_Sidebar", sidebarModel); } // 模拟获取侧边栏数据的方法,你可以替换成实际业务逻辑 private SidebarViewModel GetSidebarMenuData() { return new SidebarViewModel { /* 填充你的侧边栏数据 */ }; } }这里的参数和控制器方法的
[OutputCache]一样:Duration是缓存时长(单位秒),VaryByParam控制哪些参数变化时生成新缓存(*表示任何参数变化都更新),Location指定缓存存在哪(Server就是服务器端缓存),还可以加VaryByCustom、VaryByHeader这些高级配置。在布局页里调用这个子动作
把原来的@Html.Partial("_Sidebar")替换成调用子动作的代码就行:@Html.Action("Sidebar", "Home") // 要是追求一点性能,也可以用RenderAction直接输出到响应流: // @{ Html.RenderAction("Sidebar", "Home"); }
方案二:在视图里手动用缓存API实现
如果不想加子动作,也可以直接在布局页里手动写缓存逻辑,灵活度更高:
@{ // 定义唯一的缓存键,要是侧边栏和用户相关,记得加上用户标识(比如用户名) var cacheKey = $"Sidebar_Cache_{User.Identity.Name}"; var cachedSidebarHtml = HttpContext.Cache[cacheKey] as MvcHtmlString; // 如果缓存里没有,就渲染部分视图并存入缓存 if (cachedSidebarHtml == null) { using (var stringWriter = new StringWriter()) { // 把部分视图渲染到字符串写入器 Html.RenderPartial("_Sidebar", null, new ViewDataDictionary(ViewData)); cachedSidebarHtml = MvcHtmlString.Create(stringWriter.ToString()); // 存入缓存,设置10分钟后过期 HttpContext.Cache.Insert( cacheKey, cachedSidebarHtml, null, DateTime.Now.AddMinutes(10), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null ); } } } // 输出缓存的内容 @cachedSidebarHtml
这种方式可以自己定义缓存键、过期策略、缓存优先级,但需要手动处理缓存逻辑,适合对缓存有特殊定制需求的场景。
小提醒
- 如果侧边栏是用户专属内容(比如显示用户昵称、个人菜单),一定要在缓存键里加入用户标识,或者在子动作的
[OutputCache]里加VaryByCustom = "User",然后在Global.asax里重写GetVaryByCustomString方法来处理用户维度的缓存区分,不然会出现不同用户看到相同侧边栏的问题。 - 缓存时长要根据内容更新频率设置,比如菜单很少改就设长一点,要是经常变就设短一点。
内容的提问来源于stack exchange,提问作者Abdul Rehman Sayed
相关产品推荐
相关产品推荐

