4

I am using Razor view engine in ASP.Net MVC 3 RC 2. This is part of my view city.cshtml

(drastically simplified code for the sake of simplicity in example)

<!-- in city.cshtml -->
<div class="list">
@foreach(var product in SQL.GetProducts(Model.City) )
{
  <div class="product">
    <div>@product.Name</div>
    <div class="category">
    @foreach(var category in SQL.GetCategories(product.ID) )
    {
      <a href="@category.Url">@category.Name</a> » 
    }
    </div>
  </div>
}
</div>

I want to cache this part of my output using OutputCache attribute, so I created an action ProductList with OutputCache attribute enabled

<!-- in city.cshtml -->
<div class="list">
  @Html.Action("ProductList", new { City = Model.City })
</div>

and I created the view in ProductList.cshtml as below

<!-- in ProductList.cshtml -->
@foreach(var product in Model.Products )
{
  <div class="product">
    <div>@product.Name</div>
    <div class="category">
    @foreach(var category in SQL.GetCategories(product.ID) ) 
    {
      <a href="@category.Url">@category.Name</a> » 
    }
    </div>
  </div>
}

but I still need to cache the category path output on each product. so I created an action CategoryPath with OutputCache attribute enabled

<!-- in ProductList.cshtml -->
@foreach(var product in Model.Products ){
  <div class="product">
    <div>@product.Name</div>
    <div class="category">
      @Html.Action("CategoryPath", new { ProductID = product.ID })
    </div>
  </div>
}

But apparently this is not allowed. I got this error:

OutputCacheAttribute is not allowed on child actions which are children of an already cached child action.

I believe they have a good reason why they need to disallow this. I really want this kind of nested Output Caching.

Any idea for a workaround?

1

4 Answers 4

2

We had a similar issue, and found that we didn't actually NEED nested partial output caching at all. Once we were caching the parent object, the child was not called again until the parent's cache expired.

So, my advice might be: Cache the parent and the child will already be handled.

Sign up to request clarification or add additional context in comments.

Comments

2

Use Child Action Cache For CategoryPath Action. There's also an example of ChildActionOnly in action.

1 Comment

can you give example of usage?
1
+100

In you SQL.GetCategories method you can get all categories and cache it if not already in cache. And filter categories by productID using LINQ TO OBJECTS. In this way you do not hit db every time you need to find categories of a product.

Now you only use OutputCache on ProductList, and you have a pretty decent performing (partial)view.

2 Comments

+1 for your advice to cache categories. but what I'm looking for is a workaround to enable this kind of nested output caching. the actual code is more complicated than the example
I guess there is no workaround. so I took your advice to use the OutputCache on ProductList and create custom cache for product's category path.
0

I don't know much about MVC, but "nested caching" made me wonder why using varybyparam won't work here...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.