Reputation: 4309
I'm having issues with OutputCache for a partial view action. My index action controller is defined like so...
<OutputCache(Duration:=3600, VaryByParam:="*")>
<Route("")>
<HttpGet>
Public Function Index(value As MySearchFilter) As ActionResult
ViewData("Title") = "Search Jobs"
Return View("Index", value)
End Function
and I have a PartialViewResult action defined like so...
<OutputCache(Duration:=3600, VaryByParam:="*")>
<Route("search")>
<HttpGet>
Public Function Search(value As MySearchFilter) As PartialViewResult
Return PartialView("_List", Search(value))
End Function
In my Index view (vbhtml), I call the partial action like so...
@Html.Action("Search")
This works fine without caching. I can see that the "Search" action is getting the correct filter object passed to it etc.
The issue I'm having is that with caching enabled, VaryByParam:="*" seems to be ignored. The result never changes, even when the querystring params change. When I debug, I can see that the action is only called the first time, and never after that.
The main "Index" action works correctly, and any change to the parameters correctly caches different content.
I know I could just use caching on the index action, and turn it off for the "Search" action, but I have a number of other partial views, and I'd like to be able to control the caching independently for each.
Note: I'm not trying to customise the cache by RouteData.Values, I'm trying to customise it by Querystring parameters, which is supposed to be exactly what VaryByParam does. In the debugger I can see that the Request.QueryString is available to controller action. I'm completely stumped, I can't understand why it's not working.
Upvotes: 1
Views: 291
Reputation: 4309
I found the solution partly from Partial Page Caching and VaryByParam in ASP.NET MVC 3
Apparently for child controller actions, it doesn't use the URL, or form parameters, but rather the controller method parameters. To determine if they've changed, it calls .ToString() on each parameter. For simple types, this is fine, but for a complex object, you must override .ToString(), otherwise it's never going to change. It'll just return the name of the class.
Just in case it's useful. This is my ToString method, which is defined in a base class which all my view models inherit...
Public Overrides Function ToString() As String
Return JsonConvert.SerializeObject(Me)
End Function
This seems to be a fairly neat/reliable way to ensure that any change to any property correctly changes the cache.
Upvotes: 0