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.
Related
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 am trying to implement caching in an MVC 4.0 ASP.net application. I can cache using outputcache
[OutputCache (Duration=60)]
public ActionResult myaction(string parm1)
{
--logic to construct the model object
-- followed by this return statement
return PartialView(model);
}
But I need to clear the cache after editing data which is stored in an xml file.
So I tried to add
HttpResponse.RemoveOutputCacheItem(Url.Action("myaction", "myController"));
in another action of the same controller before calling return RedirectToAction(myaction);
But the cache is not getting reset.
Is this the method to refresh outputcache using actions? I call these actions from jquery using ajax.
Use ICacheProvider instead.
OutputCache is very limited on what you can do.
Once you need to change the data that is cached, you can invalidate that particular data using ICacheProvider while using OutputCache, you either cache the entire ActionResult or none.
Also OutputCache does neither have the flexibility that ICacheProvider has, nor the beauty of working with it.
You may have cached the output on the user's machine instead of the server. Try specifying the Location:
[OutputCache(Location= System.Web.UI.OutputCacheLocation.Server, Duration=60]
Otherwise the cache deletion won't work because you've cached the HTML output on the user's machine
ASP.NET MVC supports donut-hole caching but not donut caching. You can cache partial views and exclude parent view BUT you cannot cache parent view and exclude partial views. Write a custom filter for caching or use https://www.nuget.org/packages/MvcDonutCaching
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.
How do I can persist data in MVC Razor without using TempData between requests?
I see when we can use TempData from this, but don't want to TempData as it creates a state on the machine.
Thanks, Anish
EDIT: I want to persist the previous sort direction in a View page where a user is allowed to sort fields such as Name, Age etc.
FIX: I fixed it using ViewBag. Previous sort field/direction sent to View from Controller using ViewBag and then passed it back as query string in the next click.
Good FIX: I handled the everything in .js file such as checking and then in setting the previous sort field and previous sort dir in Controller.
This is what I finally did. I used ViewBag to send previous details to ViewPage and did the validation in a .js based on the current user action and passed it back to the controller in form-data.
Maintaining State in client page is something which is breaking the concept of HTTP which is stateless. Why do you want to maintain state ? If you are looking for some solution for Passing some data from your controller action to corresponding view, i would suggest you to go with a ViewModel where you fill the data for the dropdown and send that ViewModel object to the strongly typed view. You will have your data available there. Also you should grab data from your DataLayer ( from tables/ or Cache or etc..) in every request if you want some data.
You may pass a relevant id in the query string to get the corresponding data.
As RTigger mentioned, you may store some data in session. That will be available across all the pages till the life time of that session.
I haven't done a lot of ASP.NET MVC 3 recently, but I think the only real way you can persist data across requests is either with session state, cookies, or by posting data to the server every request.
ViewData, ViewBag, and TempData are all effectively killed at the end of each request, whereas session state, cookies, and post data is made available at the beginning of every request based on information from the client browser.
What particular scenario are you trying to persist data for?
You could pass those values as query string parameters when redirecting.
You can set parameters to hidden input fields if you post the form. But if you gonna call action by HTTPGET then you can pass values by using QueryString parameters.
i have read a few different things, it sounds like output cache will not cache a different copy of results for each user. so if user A has 3 menus and user B only has access to 1 of them, then caching the view result would show all 3?
how can i cache things for each user so that it's not shared?
thanks!
Use VaryByCustom and redefine HttpApplication.GetVaryByCustomString:
public virtual string GetVaryByCustomString(
HttpContext context,
string custom
)
{
//Return a value unique per user
//Change depending on the authentication of your site (f.e. make use of Session)
return context.User.Identity.Name;
}
http://msdn.microsoft.com/en-us/library/system.web.httpapplication.getvarybycustomstring.aspx
http://asp.net-tutorials.com/caching/more-output-cache/
One solution is to pass a parameter with the number of menus. Then configure outputcache to cache by all parameters except this one.
Also you can configure output cache to cache only on the client, not on the server It might be useful depending of your scenario.
You can always cache user specific information on the asp.net session.