I am using MVC 2 and am having problems getting the OutputCache to work. My ASP.NET website has Several Views and a View Master Page. On my View Master Page I have a Menu on the left hand side displaying navigation links (implemented using JQuery).
I have implemented the Menu as a PartialView and I call this PartialView from my MasterPage using Html.RenderAction. This all works fine, my controller fetches the data from the database and the PartialView is populated.
The problem is I want to cache the Menu data since it's consistent on all pages. Yet when I add the OutputCache parameter to my Action it has no effect.
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IQueryable<LMA.Data.SiteMenu>>" %>
<div id="accordion">
<% foreach (var menu in (from m in Model where !m.ParentID.HasValue select m).ToList())
{%>
<h3>
<a href="#">
<%= menu.Name %></a></h3>
<div>
<%
foreach (var subMenu in (from s in Model where s.ParentID.HasValue && s.ParentID == menu.ID select s).ToList())
{%>
<%: Html.ActionLink(subMenu.Name,subMenu.Action,subMenu.Controller) %><br />
<%
} %>
</div>
<% } %>
</div>
** Master Page **
Does anyone have any idea why the caching doesn't work?
Thanks for the reply, can you recommend any other way I can achieve this? I was going to use the Cache Class directly in my Repository but this is in my DataAccess layer and I didn't want to introduce a dependency on System.Web.Caching here?
I also tried to implement an ActionFilter Attribute but this had the same problem.
The only other place I thougth of doing this was in the Repository where I could access the Cache Class directly though HttpContext.Current.Cache. The problem is my Repositories are based in my DAL and I didn't want to introduce a dependency on System.Web
here.
Thanks for this and the info. on MVC 3. In the end I decided to using the Cache class directly in my Controller. I found it to be straightforward to implement and consistent with my MVC architecture.
Can you see any big drawbacks in this approach?
public class ApplicationController : Controller
{
private Cache _cache;
private readonly IMenuRepository _repo;
public ApplicationController():this(new MenuRepository()){}
public ApplicationController(IMenuRepository repository)
{
_repo = repository;
_cache = System.Web.HttpContext.Current.Cache;
}
public PartialViewResult Menu()
{
IQueryable<SiteMenu> result;
try
{
result = (IQueryable<SiteMenu>)_cache["menu"];
if (result == null)
{
result = _repo.GetMenu(HttpContext.User.Identity.Name, Membership.ApplicationName);
_cache.Insert("menu", result, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
_cache["menu"] = result;
}
}
catch (Exception)
{
throw;
}
return PartialView(result);
}
}
Just one final question on this, I went through the Doghnut Hole example and could see how the date was cached in the ViewUserControl. However, if I set a breakpoint in the Controller Action it is hit when I press refresh and the data is retrieved from the
repository (which in the case of the demo is a IEnumerable<Joke> populated statically in code, but in my case it's populated from the db).
I would have thought that the Controller Action wouldn't be hit if the page was cached. How is the caching working in this instance?
More comprehensive caching solutions are currently on the slated feature list for MVC 3.
If you're using .NET 4, you can also use the MVC Futures [ChildActionCache] action filter. Stick it on the action method that's the target of the RenderAction(): [ChildActionCache(Duration = 10)], duration measured in seconds.
The [ChildActionCache] filter can be found in the Microsoft.Web.Mvc.Aspnet4.dll binary that's included with the MVC Futures zip. Visit http://aspnet.codeplex.com/releases/view/41742 to download.
ClickAhead
0 Points
6 Posts
Problem with OutputCache when using RenderAction and Partial View
May 17, 2010 07:29 PM|LINK
Hi All,
I am using MVC 2 and am having problems getting the OutputCache to work. My ASP.NET website has Several Views and a View Master Page. On my View Master Page I have a Menu on the left hand side displaying navigation links (implemented using JQuery).
I have implemented the Menu as a PartialView and I call this PartialView from my MasterPage using Html.RenderAction. This all works fine, my controller fetches the data from the database and the PartialView is populated.
The problem is I want to cache the Menu data since it's consistent on all pages. Yet when I add the OutputCache parameter to my Action it has no effect.
** Action **
[OutputCache(Duration = 30, VaryByParam = "None")] public PartialViewResult Menu() { IQueryable<SiteMenu> result; try { result = _repo.GetMenu(HttpContext.User.Identity.Name, Membership.ApplicationName); } catch (Exception) { throw; } return PartialView(result); }** Partial View **
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IQueryable<LMA.Data.SiteMenu>>" %> <div id="accordion"> <% foreach (var menu in (from m in Model where !m.ParentID.HasValue select m).ToList()) {%> <h3> <a href="#"> <%= menu.Name %></a></h3> <div> <% foreach (var subMenu in (from s in Model where s.ParentID.HasValue && s.ParentID == menu.ID select s).ToList()) {%> <%: Html.ActionLink(subMenu.Name,subMenu.Action,subMenu.Controller) %><br /> <% } %> </div> <% } %> </div>** Master Page **
MVC - 2 OutputCache PartialView RenderAction
Nick_Uk
Participant
800 Points
445 Posts
Re: Problem with OutputCache when using RenderAction and Partial View
May 17, 2010 08:39 PM|LINK
Is it possible you have set caching elsewhere that negates/overrides this?
Site
Blog
bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: Problem with OutputCache when using RenderAction and Partial View
May 17, 2010 08:57 PM|LINK
Most action filters no-op during child actions, including OutputCache.
ClickAhead
0 Points
6 Posts
Re: Problem with OutputCache when using RenderAction and Partial View
May 17, 2010 09:47 PM|LINK
Hi Brad,
Thanks for the reply, can you recommend any other way I can achieve this? I was going to use the Cache Class directly in my Repository but this is in my DataAccess layer and I didn't want to introduce a dependency on System.Web.Caching here?
I also tried to implement an ActionFilter Attribute but this had the same problem.
Many Thanks,
Ciaran
ClickAhead
0 Points
6 Posts
Re: Problem with OutputCache when using RenderAction and Partial View
May 17, 2010 09:58 PM|LINK
Hi Nick_Uk,
The only other place I thougth of doing this was in the Repository where I could access the Cache Class directly though HttpContext.Current.Cache. The problem is my Repositories are based in my DAL and I didn't want to introduce a dependency on System.Web here.
bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: Problem with OutputCache when using RenderAction and Partial View
May 17, 2010 09:59 PM|LINK
The "user control" solution still works with MVC 2, as far as I know.
http://haacked.com/archive/2009/05/12/donut-hole-caching.aspx
More comprehensive caching solutions are currently on the slated feature list for MVC 3.
http://aspnet.codeplex.com/wikipage?title=Road%20Map
ClickAhead
0 Points
6 Posts
Re: Problem with OutputCache when using RenderAction and Partial View
May 17, 2010 10:34 PM|LINK
Hi Brad,
Thanks for this and the info. on MVC 3. In the end I decided to using the Cache class directly in my Controller. I found it to be straightforward to implement and consistent with my MVC architecture.
Can you see any big drawbacks in this approach?
public class ApplicationController : Controller { private Cache _cache; private readonly IMenuRepository _repo; public ApplicationController():this(new MenuRepository()){} public ApplicationController(IMenuRepository repository) { _repo = repository; _cache = System.Web.HttpContext.Current.Cache; } public PartialViewResult Menu() { IQueryable<SiteMenu> result; try { result = (IQueryable<SiteMenu>)_cache["menu"]; if (result == null) { result = _repo.GetMenu(HttpContext.User.Identity.Name, Membership.ApplicationName); _cache.Insert("menu", result, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30)); _cache["menu"] = result; } } catch (Exception) { throw; } return PartialView(result); } }bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: Problem with OutputCache when using RenderAction and Partial View
May 18, 2010 02:41 AM|LINK
Seems reasonable to me.
ClickAhead
0 Points
6 Posts
Re: Problem with OutputCache when using RenderAction and Partial View
May 18, 2010 10:18 AM|LINK
Hi Brad,
Just one final question on this, I went through the Doghnut Hole example and could see how the date was cached in the ViewUserControl. However, if I set a breakpoint in the Controller Action it is hit when I press refresh and the data is retrieved from the repository (which in the case of the demo is a IEnumerable<Joke> populated statically in code, but in my case it's populated from the db).
I would have thought that the Controller Action wouldn't be hit if the page was cached. How is the caching working in this instance?
levib
Star
7702 Points
1099 Posts
Microsoft
Re: Problem with OutputCache when using RenderAction and Partial View
May 18, 2010 06:01 PM|LINK
If you're using .NET 4, you can also use the MVC Futures [ChildActionCache] action filter. Stick it on the action method that's the target of the RenderAction(): [ChildActionCache(Duration = 10)], duration measured in seconds.
The [ChildActionCache] filter can be found in the Microsoft.Web.Mvc.Aspnet4.dll binary that's included with the MVC Futures zip. Visit http://aspnet.codeplex.com/releases/view/41742 to download.