Search code examples
asp.net-mvcoutputcachecustom-action-filter

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?


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