views:

313

answers:

1

Hello,

I have a simple proof of concept that seems to be handling caching oddly. Here's the view:

<script>       
$('#clickToLoad').click(function() {
    $.ajax({
        url: "<%=ResolveUrl("~/Home/AjaxCacheTest") %>?"
        , dataType: 'json'
            ,ifModified: true
            ,cache: true
        ,success: function(sourceData) {
        }
    });
});
</script>

This is linked to an action in the controller:

[OutputCache(VaryByParam = "none", Duration = 3000)]
public ContentResult AjaxCacheTest()
{
    return Content("0", "application/json");
}

I'd like to get a result with caching, however, it seems that AjaxCacheTest doesn't cache unless I request it on its own (that is, in a browser window, instead of AJAX).

Setting cache: true doesn't help. Setting ifModified: true does cause caching, but then it doesn't call the success function, so I can't use the results.

Are there any options that allow caching and still call the response callback?

UPDATE: Thanks, forgot to add those. I'm testing with firebug and determining how caching is handled by a combination of looking at the response code (200 OK vs 302) and the response time for the request. This is all on Visual Studio's built in server (Cassini?).

A: 

Here's how the caching in your scenario works. Suppose you define the following action

[OutputCache(VaryByParam = "none", Duration = 5)]
public ActionResult AjaxCache()
{
    return Json(new { date = DateTime.Now }, JsonRequestBehavior.AllowGet);
}

If you don't explicitly set the Location attribute it default to OutputCacheLocation.Any which means:

The output cache can be located on the browser client (where the request originated), on a proxy server (or any other server) participating in the request, or on the server where the request was processed. This value corresponds to the HttpCacheability.Public enumeration value.

Duration = 5 means that the contents will be cached for 5 seconds. Next you send ajax request:

<%= Html.ActionLink("cache test", "AjaxCache") %>

<script type="text/javascript">
$(function() {
    $('a').click(function() {
        $.ajax({ url: this.href,
            success: function(json) {
                $('#result').html(json.date);
            }
        });        
        return false;
    });
});
</script>

<div id="result"></div>

If you click on the link twice during 5 seconds interval you will see that the result div will not change neither the server action will be hit but the success callback will always execute. The server sends the following headers:

Cache-Control: public, max-age=5
Expires: Fri, 26 Feb 2010 14:09:02 GMT
Last-Modified: Fri, 26 Feb 2010 14:08:57 GMT
Vary: *
Darin Dimitrov
Looks like this is somewhat working...I had to upgrade to MVC 2 to try it, perhaps that had something to do with it. It's no longer sending 304s, just 200s. I'll do some more testing and figure it out later, thanks.
Chris
Yup, this works in MVC 2, don't know what was broken in MVC 1.Just one warning; at least in my case, I had to add dataType: 'json' to the ajax call. Thanks!
Chris