Outputcache override with query string showing non cache version in asp.net mvc - asp.net-mvc

Id like to show a page non cached, but still take advantage of outputcache. Say a admin would like to see the page updated in real time by adding a query string nocache=1 to the url, then the outputcache wouldnt show the cached version, but if the query string is left off it would. Can I do this?

The best alternative would probably be to implement a custom cache provider which, when given a certain set of parameters, does not cache the page. Here is one such example:
http://www.haneycodes.net/custom-output-caching-with-mvc3-and-net-4-0-done-right/

If you create some miscellaneous parameter and configure the output caching to varyByParam, you should be able to call it with different values each time, it should bypass the cache... However I'm not sure this would be the best way to do that. You may want to just create a separate action for the admin to access that is secured.

Related

How to bust the cache or obtain cache key when using <distributed-cache> Tag helper in Asp.net Core MVC

Having an issue with the <distributed-cache> tag and Redis.
We have a <partial> Razor view that displays results of a long-running query. We acquire the data from a service injected in using #inject. The data updates very rarely, hence we wrap the content in a <distributed-cache> tag helper, with a long expires-after attribute.
However, when the data is finally updated (in another part of our app), we need to delete that key from the distributed cache, in order to force the page to update on next execution. (It's not possible for us to predict when the data will change - we can only respond to an external event.)
The problem we're having is that, despite having a fixed name attribute, the cache key appears to be impossible to predict. For example <distributed-cache name='_myQuery' vary-by-user='true'> creates a key something along the lines 7/za/Bc/ZRn/MsR/hG69TYTx1LEzqBvlyH1OLJgrpk4= in Redis.
How can I either:
Predict/calculate what the cache key is going to be in redis, so that I can delete it in another part of our application?;
Force the <distributed-cache> tag to ignore the cached value this one time? I know we have the enabled property, because this isn't going to work because the page doesn't know when to invalidate the cache.
After digging into the ASP.NET Core source I've found the CacheTagKey.cs file, which contains the GenerateKey() and GenerateHaskedKey() methods. These methods create the key from a bunch of params, then SHA256 hashes the key and returns base64.
So it looks like I can use this to predict the cache key and solve the issue.

Is it possible to resolve navigation outcome in order to validate it?

I've got a WebFilter that redirects to the login page in my application. In order to redirect back to the referring page I've also added a view parameter called redirectOnLogin which is then used on successful logins in order to perform the final navigation.
If one were to manipulate this query parameter, one could easily provoke JSF navigation errors. I would therefore like to pre-empt this by checking that the outcome is valid but I've not been able to uncover a mechanism for pre-validating a JSF outcome.
Easiest and best is to make sure the redirectToLogin parameter cannot be manipulated. Or that manipulation is detected.
You could solve this in (at least) two ways
Taking the original page name, adding a 'salt' to it and creating a hash.
Addin this has that in the request to the login server
Make sure it is returned by the login server (maybe adding it as # to the return page or as a param.
On receiving it on the 'redirectOnLogin' page, use the page name, the same salt and create a hash in the same way. Compare these and if they match you are fine, if they don't throw an error.
Or you could
Store the 'redirectOnLogin' page in a session to
Check on returning from the login server if it matches with the page you end-up on.

Proper way to remember multiple parameters across requests in Rails

My application feature a "main" page where most of the action happens: There are tags for filtering and a list of results in a (paginated) table, plus the possibility to select some or all results in a "shopping cart".
This page has to keep track of a whole lot of things: what tags are selected, what items are selected, and how the result table is sorted and what page it's on. Everything has to persist, so if I select a new tag, the page must partially reload but remember everything (sorting, what's selected).
Right now I'm handling everything with parameters, and for each action taken on the page, all links (select a tag/item, change page, sort table) are updated to include previous parameters + the relevant new addition. This works, obviously, but it feels kind of inefficient, as I have to reload more of the page than I want to. How is this situation normally handled? I can't find that much info on google at all, but it doesn't feel like a particularly uncommon case.
tl;dr: How to best make sure all links (to the same page) always include everything previously selected + the new action. There are a lot of links (one per tag to select/deselect, one per result item to select/deselect, one per sort option, one per page)
There are five ways to do that:
Method 1: By parameters
You mentioned this. I never think of this as it's too troublesome. Anyway it's still a solution for very simple case.
Method 2: By cookie
Save the settings to a cookie and read the cookie in controller to arrange layout settings.
Method 3: By LocalStorage
Similar to cookie but allows more space.
Method 4: By Session
If you are using ActiveRecord to save session, this could be the best solution for pure pages loading. Save the user preferences into session and load it in next layout.
Method 5: Use Ajax
This is the best solution IMO. Instead of whole page loading, use Ajax to refresh/retrieve changes you need. Using together with above method, a user can even continue his last preferences. This is the most powerful and should be applicable to your case which looks like a web app than a website.
Have you tried creating model for all those attributes? and just always load the 'latest' when on the page load, if you dont need them you can always have a flag for that session.

Maintain parameter info in the request path for all pages instead of the subdomain

I seek some guidedence here ... ( I'm not sure if this is the best title )
At the moment I prepend a "server name" to the url like this:
server10.example.com
This works fine, except that I need to handle all the subdomains on the IIS and I'm not sure google are happy about jumping around from sub to sub to sub, when it seems the links to the other servers.
I'm kind a hoping for a nice way to archive this wioth asp.net mvc.
Most pages are related to a "server" ... there are however a few info pages, contact, home that dont really need a valid "server" name ... but could just be "na" for not available, but the name need to be maintained, if there is already a selected server, when a user are keeps browsing the site. This needs to be as transparent as possible when I need to create the links to the diffenrent pages.
I could extend the Html Action() extensien to automatically add the selected "server" from the previusly request to the page.
In the format:
/{serverParameter}/{controller}/{action}/{parameterInfo}
And if no server is selected, just add "na" as the {server} placeholder.
I'm not sure if more information is needed, but please let me know if ...
I tired of extracting the selected server from the domain part and the other way also seems better, I just can't think of a good way to structure this ...
Updated
90% of all the pages are about a server that the user select at some point. Could be server10, server9, server20 ... just a name. I want to maintain that information across all pages, after the users has selected it or else I just want it to be f.ex: "empty".
I mostly looking for an easy way of doing this or an alternative ... atm I'm prepending the serverParamter to the url so it ends up being: "serverParameter.example.com".
I want to end up with something like
http://example.com/{server}/{controller}/{action}
instread of
http://{server}.example.com/{controller}/{action}
If I understand your question correctly, you just wish to group different collections of content together above the controller/action level. If that's the case, have you considered using ASP.NET MVC areas?
Just right-click on your project, and choose Add -> Area.... Give it a name (what you're calling "server"), and then you can add content, your own controllers, actions, etc. Under this area. You will automatically be able to access it via /AreaName/Controller/Action/etc.
I went with the already impemented routing in ASP.NET MVC.
{server}/{controller}/{action}
When creating the links it takes the set value for {server} and places the value when generating URL's, so I only need to supply controller and action in the #Html.Action helper method ... this could not have been more easy.
I'm not sure why I did not think about this. One just gotta love routing.

OutputCache and recording unique views?

Image i have a view that is cached with the OutputCache attribute but i still need to increment a counter that records that the page has been viewed, how could i do it?
I thought about creating my own Custom ActionFilterAttribute, and using Action Filter Order of Execution to record this .. but i'm not sure it will work.
eg.
[IncrementViewCountFilter(Order=1)]
[OutputCache(Duration=60,Order=2)]
public ActionResult Index(int questionId)
{ ... }
Firstly, my assumption here is that if the OutputCache is called, and the page is cached, then the controller code will not be ran.
Next problem i'm guessing is that the IncrementViewCountFilter wouldn't know about the questionId, so how would it know what to increment (because it is executed before the main Index code is executed).
Secondly, if the IncrementViewCountFilter did know the questionId .. and it's getting lots of hits, you wouldn't want it to write all the time to the DB.. but only when it gets to a certain number .. and then u 'flush' the output.
Anyone have any thoughts?
Well, you have a few options.
Donut caching
One server-side option is 'Donut caching'. Donut caching allows most of the page to be cached, and portions of the page to be not cached (the hole in the middle of the donut). Donut caching is described here, and I have used it with great success.
Image-based tracker
Another option is having an image on the page actually load a server-side action that records the hit. This would look like
<img src="/controller/action">
on the page, where the action serves up an empty image at the end.
Client-side tracking
The last option is client-side tracking -- where some script runs on the client side and uses AJAX to call something on the server to record the hit. Google uses something like this for their Analytics package. If you're on the same domain as your tracking mechanism ... like if your main page is:
http://www.domain.com/home/action
and the tracker is on
http://www.domain.com/tracking/action
then you should be fine.
This gets tricky when your tracker is on a different domain (you need to handle this using JSONP or some other mechanism that allows for relatively safe cross-site scripting).
The filter can get the questionId from the ActionExecutingContext.ActionParameters, which is passed to OnActionExecuting. As for caching the hit counts, well, use the cache. :)
You could also use an HttpModule which is a good option because it can be used for pages and other assets that do not use the MVC pipeline. I use a combination of Donut caching,(http://mvcdonutcaching.codeplex.com/), an MVC filter and an HttpModule to record all types of analytics for cached pages.
I don't know about the MVC side but if I was doing this in WebForms this sounds like it would be a candidate for output cache substitution aka donut caching.

Resources