Question

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?

Was it helpful?

Solution

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).

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top