In my MVC project I am using OutCache for caching a page. And I also use .htaccess so that for 2-3 different url it gets same page.
I am using VaryByParam to store page in cache. When I hit the any one url with some query string it store the output in cache perfectly but when I hit the different url (which redirect to the same controller as for the first one) with same query string which I used first time it will store different copy for this time.
I don't understand why it is happening as VaryByParam stores data based on Query String and not based on the URL.
Here is my code.
Controller: Main.cs
[OutputCache(Duration=200,VaryByParam="*")]
public ActionResult Details(Filter filter)
{
//some code
}
here Filter is Class to store query string based on its parameter.
.htaccess
RewriteRule ^cars/get-details/ /main/details/ [QSA,NC,L]
So when I hit http://localhost/main/details/?car=1 it store page in cache and works fine if I hit same url I will get data from cache but when I hit http://localhost/cars/get-details/?car=1 rather then fecthing from cache it store another copy for this.
I don't understand why it is happening.Any help would work.
Related
I have a site whose layout contains some partial views. One for the page header, other for a menu that is shown to the left, and other for a page footer.
The body is not a partial view. Just a #RenderBody() call.
I need to increase page loading so I tried to use DevTrends.MvcDonutCaching.DonutOutputCache attribute.
The problem I have is that the page header shows information about the current session that changes according which option the user chose at log in time.
Look at one Index action in a controller:
[DevTrends.MvcDonutCaching.DonutOutputCache(Duration = int.MaxValue, VaryByParam = "none", Location = System.Web.UI.OutputCacheLocation.Client)]
public async Task<ActionResult> Index()
{
return View();
}
Well... with that, the client browser will store the whole page, including, of course, the header.
The bad thing with this is that if the user logs out and logs in again chosing other option, the header shows the options chosen in the previous session, unless user presses Ctrl-F5 to reload the page clearing the cache.
I had set the cache location in the server at first, but that was the worst. The same header appears for all uses that log in to the system. That is why I changed location to client.
When user logs out the session, I am running this code:
var cacheManager = new DevTrends.MvcDonutCaching.OutputCacheManager();
cacheManager.RemoveItems();
That did not work either.
I was thinking to stop using caching at all, trying to delete cache using some Javascript function or searching for a way to not store in cache the page header.
What is your advice with this?
Thanks
Jaime
I need to cache the page specific to logged in user. So I used as mentioned below:
[OutputCache(Duration = 10, VaryByParam = "Id", Location = OutputCacheLocation.Client)]
public ActionResult PartialPageOutputCaching(string Id)
{
return PartialView("PartialPageOutputCaching");
}
OutputCacheLocation.Client did not work for me as it is serving new request every time. I tried to search storing page output cache specific to user, but could not find the right working sample. Please let me know, how OutputCacheLocation.Client suppose to work.
I tried VaryByParam = "Id" assuming that, based on the action methods parameter page content will be cached, but looks like it works on query string parameter. Please confirm how VaryByParam suppose to work.
Thanks in advance.
OutputCacheLocation.Client means that it will cache on the client, meaning in the browser your user is using. Also there is really not much advantage of caching for a specific user, as user already has the page rendered and chances that he will open the same page are small to take advantage of that cache.
I have an action declared as following
[Route("{language}/Navigation/Test")]
[OutputCache(Duration = 3600, VaryByParam = "none")]
public ActionResult Test()
{
return View();
}
In order to check outputcache setting I added #DateTime.Now.Ticks.ToString() in view Test.cstml
What troubles me is that when i run http://localhost/EN/Navigation/Test first time, view gets cached and page refresh returns a same number of ticks. Now if i change language and set http://localhost/DE/Navigation/Test number of tick changes, ie. view is not served from cache.
I tried to remove VaryByParam = "none" but is always produces the same results.
What is wrong here, how to serve a cached view not matter what language is used.
VaryByParam varies by the parameters passed in a URL. I.e. The URL www.stackoverflow.com/page?param1=5. Because DE is a different URL to EN, the page won't be found in the cache so it requests a new one.
From MSDN
A semicolon-separated list of strings used to vary the output cache. By default, these strings correspond to a query string value sent with GET method attributes, or a parameter sent using the POST method. When this attribute is set to multiple parameters, the output cache contains a different version of the requested document for each specified parameter. Possible values include none, *, and any valid query string or POST parameter name.
Bottom line: It's based on URL, not routing. You are able to configure based on the query string but no more.
I'm using OutputCache for caching an horizontal menu and a vertical menu in my app. I usually use something like this in the actions I want to be cached
[OutputCache(Duration=3600, VaryByParam="none", Location=OutputCacheLocation.Client, NoStore=true)]
public ActionResult ActionName()
{
.......
}
But if it is a child actions i must use
[ChildActionOnly]
[OutputCache(Duration = 180, VaryByParam = "none")]
public ActionResult Menu()
{
......
}
When you use OutputCache with child actions you can´t specify properties like Location or NoStore. So the question is, if i can´t specify the cache location (client, server, any) for a child action, where is it stored by default?? Thanks!!
(sorry for my english)
I'm just guessing here, but it would probably get stored just on the server. The idea of a partial view (likely the result of a child action) being stored on the client doesn't make sense -- the client doesn't have any idea of the page's action break-down on the server.
The way I see it, unless the entire page is cached, the client must go to the server to get the page rendered, at which point, the server can returned the cache child action result.
When we use Output Cache for child action it is cached on Server not on client side.
Unfortunatly it is cached on client, Just set a breakpoint on your childAction Method, and run application from multiple browsers, for each browser ChildAction will called in cache duration.
Im thinking in use the Output cache attribute for caching views in MVC.
My question is simple:
When i use output cache attribute on top of an action method, if in the next request the view was cached the action is not executed right?
Yes, you are correct. This is easliy tested:
[OutputCache(Duration=10, VaryByParam="id")]
public function TestCache()
{
return Content(" I was generated at " + DateTime.Now);
}
However, you can invalidate the cache using the VaryByParam property, which allows you to control the cache depending on request parameters or similar.
In my example, the cache will vary depending on which id is specified in the request parameters. This is useful when you have a dynamic page which loads data from the database.
Yes you are right , the cached action is not executed unless you use varyByParam or some other property of that attribute.