views:

6166

answers:

9

Hey all, I'm playing around with ASP.net MVC and JQuery at the moment. I've come across behavour which doesn't seem to make sense.

I'm calling JQuery's $.getJSON function to populate some div's. The event is triggered on the $(document).ready event. This works perfectly.

There is a small AJAX.BeginForm which adds another value to be used when populating the divs. It calls the remote function correctly and upon success calls the original javascript function to repopulate the divs.

Here is the weird part: In FireFox and Chrome - Everything works. BUT In IE8 (Beta) this second call to the populate Div script (which calls the $.getJSON function) gets cached data and does not ask the server!

Hope this question makes sense: In a nut shell - Why is $.getJSON getting cached data? And why is it only effecting IE8?

+2  A: 

You may need to send a cache-breaker.

I would recommend using $.ajax( { cache: no }) just in case ( adds a random suffix to the get request)

( I tend to use $.ajax everywhere these days, more tuneable )

Kent Fredric
Thanks for your answer!... i haven't tried it out yet. Will provide feed back shortly
Harry
+4  A: 

Thanks Kent for your answer. Using $.ajax('{ cache: no }'); worked perfectly. [edit]

Or at least I thought i did. Seems that the jquery $.getJSON isn't reading any changes made to the $.ajax object.

The solution that ended up working was to add a new parameter manually

var noCache = Date();
$.getJSON("/somepage/someaction", { "noCache": noCache }, Callback);

the date resolution is only to the minute; which effectively means this solution still caches for upto one minute. This is acceptable for my purposes.

Harry
var noCache = new Date().getTime(); //will give you to the ms
scunliffe
thanks Scunliffe! - i'm pretty new to javascript, ASP MVC has opened new horizons for me
Harry
You can also try something like Math.Random().
Falkayn
+17  A: 

Just to let you know, Firefox and Chrome consider all Ajax request as non-cachable. IE (all versions) treat Ajax call just as other web request. That's why you see this behavior.
How to force IE to download data at each request:

  • As you said, use 'cache' or 'nocache' option in JQuery
  • Add a random parameter to the request (ugly, but works :))
  • On server side, set cachability (for example using an attribute, see below)

Code:

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}
Nico
This solution appeals to me. I really like the elegance of applying an attibute in MVC
Harry
There is an OutputCacheAttribute OOTB nowadays.
bzlm
@bzlm but this is easier to search for
Simon_Weaver
+26  A: 

This is how it worked for me...

$.ajaxSetup({ cache: false });
$.getJSON("/MyQueryUrl",
   function(data) {
     // do stuff with callback data
     $.ajaxSetup({ cache: true });
   });
Jitesh
I was struggling with this problem and your solution gave a quick way to solve it. :)I have a question, do you know what options can be used for $.ajaxSetup? jQuery documentation does not provide details unfortunately...
Achimnol
The available options are identical to $.ajax See http://docs.jquery.com/Ajax/jQuery.ajax#options for more information
Dan Esparza
A: 

Harry,

Thanks I ended up using your solution as well. Except i'm getting the time in MS. Thanks for posting.

+1  A: 

If you're using ASP.net MVC, consider adding an extension method to easily implement no caching like so:

    public static void NoCache(this HttpResponse Response)
    {
        Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.MinValue);
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetValidUntilExpires(false);

        Response.Expires = -1;
        Response.ExpiresAbsolute = DateTime.MinValue;
        Response.AddHeader("Cache-Control", "no-cache");
        Response.AddHeader("Pragma", "no-cache");
    }
Josh
Nice idea - so you call this extension method on the server during the callback right?
Guy
A: 

Exactly how do you use "public static void NoCache(this HttpResponse Response)..."?

My guess is that you call it on the server (e.g. Resonse.NoCache(); ) when the $.getJSON() call is made so that the "no-cache" is returned in the header and thus prevents IE from caching the request. I haven't tried it but it also seems like a good solution.
Guy
+2  A: 

I solved this same problem by placing the following attribute on the Action in the Controller:

[OutputCache(Duration = 0, VaryByParam = "None")]
Guy
Wonderful! Great to have alternatives (I chose this one). Thanks to all contributors!
Anders Juul
A: 

Your are really great dude.

its working with

[OutputCache(Duration = 0, VaryByParam = "None")]

Thanks, Dheeraj.