I'm using output caching for some Index views because they contain a lot of data.
I want to keep it specific for every user. because the view can differ depending on the roles.
[OutputCache(Duration = 3600, VaryByParam = "none", Location = OutputCacheLocation.Client)]
public ActionResult Index(string schooljaarparam) {
return View(_db.Lesplaatsens.Where(l => l.Schooljaar.Sch_Schooljaar == schooljaarparam).OrderBy(q => q.Lpl_Gemeente).ThenBy(q => q.Lpl_Instelling).ToList());
}
Now when someone creates a new item and returns to the Index view. How do I remove the cache of the Index page, so that the newly created item will show up in the list?
I thought this would be a common question but I did not find a solution yet.
I guess you need to use HttpResponse.RemoveOutputCacheItem()
but how do I find the route. And where can I see the current cached items in the debugger?
You can't remove the cached item because it isn't there (ie you are not caching it on the server).
When you say Location = OutputCacheLocation.Client, the browser will cache the response and won't even send a new request to your server when the user asks for the same page unless the cache expires or the user specifically asks for the latest version by hitting F5.
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.
Using VS2013, MVC 5 and pagedlist 1.17.0.0, while on the index page, I can page through the data, add a filter, and continue to page through the data without problems. When I do a Create, Edit, Details, or Delete, it always drops my filter, and puts me back to the 1st record on the 1st page. How can I keep my current filter, as well as my place in my paged list?
Example, on a date sorted list of expenses, I've set a filter on year = 2003. I'm on page 4 of the list of 2003 expenses. I look at the details of one record, and when I return to the list, I'm back on the 1st page of 2014 expenses (sorted on date descending) - I've lost both the filter, and the page I was on (page 4 in 2003).
Sorry, new at this. Thanks
I'm currently looking for a fully generalizable approach to this for complex filters, but here is what I'm using for simple filters (which looks like what you're doing now).
Add the value to the ViewBag of your details record, then pass it back to your index (your probably want to do this for your page value as well).
So your Index action method probably already looks something like this:
public ActionResult Index(int? page, string filter)
{
ViewBag.Page = page;
ViewBag.Filter = filter;
var list = // App specific magic using the filter paramter to get your list of items
return View(list.ToPagedList(page ?? 1, 25);
}
In your Index view, you might have something like this to link to your details:
#Html.ActionLink("Details", Details", new {id = item.Id})
If you change that to:
#Html.ActionLink("Details", Details", new {id = item.Id, page=ViewBag.Page, filter=ViewBag.Filter})
Then your Details action method
public ActionResult Details(int id = 0, int? page=null, string filter=null)
{
MyDetails details = // App specific magic to get a ViewModel for your details page
ViewBag.Page = page;
ViewBag.Filter = filter;
return View(details);
}
Finally, on your details page wherever you have links back to the list, add in the two additional parameters
#Html.ActionLink("Back to List", "Index", new { page = ViewBag.Page, filter = ViewBag.Filter })
Now you should keep your state as you pass through your details page.
The way I achieved it, following this tutorial, is as follows:
Make sure your filters appear in your URL. For my filter form in my
Index view I use the Html.BeginForm helper and specify GET as the
PostMethod of the form.
In my Create/Delete/Update actions I create a ViewBag containing the Referrer URL (Request.UrlReferrer). I use this ViewBag to create
a link to the previous page with
href="#ViewBag.ReturnURL"
Good luck!
Another way to do this is to use session variables, then one doesn't have to artificially pass things around.
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.
I have an image gallery which has the following route:
// gallery id
routes.MapRoute(
"gallery-route",
"gallery/{galleryID}/{imageID}/{title}",
new { controller = "Gallery", action = "Index", galleryID = (string)null, imageID = (string) null, title = (string) null},
new { galleryID = #"\d+" }
);
I can have URLS like :
example.com/gallery/4/23 - shows
gallery 4 and image 23
example.com/gallery/4 - shows
gallery 4 and first image in that
gallery
I was trying to make an 'edit in place' mode which lets an administrator edit the images and running into several issues. Currently the editing functionality is non-AJAX.
1) How should i keep a 'sticky' edit mode parameter. There won't be an 'edit' button next to each image. i want the edit mode to be 'sticky', but then I'm finding I either need to set it in session or add a parameter to every single link on the page which is clumsy.
2) I have caching enabled for this view. Therefore if i make a change and refresh - the original cached view remains.
Can anyone give me any thoughts?
why not change the output on the view depending on the users authorisation status. Using inline code and Html helper functions in the ascx to either write out the values in HTML for readonly roles and for editor roles add a post form around input controls with the current values in. Then on the controller handle post in a separate procedure to save the edits.
or simply add an edit view ascx as well as a read view ascx.
Also when the post controller procedure fires replace the cache object with the new data recorded in the post.
finally of you have image caching problems when administering the gallery. Try adding a random string to the query eg:
function GetNewUrl(url)
{
Random rnd = new Random();
return url +"?"+rnd.Next(1000).ToString();
}
You need to flush the cache for the page when a change is made. Don't show the cached page or cache the page when the user is logged in as administrator, as they will have a different view with edit controls etc. For a sticky mode where an administrator can choose to be in edit mode throughout the site this would have to be stored in the session. I use something based on this for caching controller actions, with an additional method to determine whether to cache the output/use the cached output.