MVC3 does not support JSONP natively. An employee from Microsoft called Ranju has blogged his approach to adding JSONP to MVC3. I like his implementation and it's a pretty straight forward copy/paste to use in your projects. Check it out here: blogorama.nerdworks.in
However if the data takes too long to generate you might want to cache the output.
This is where you run into problems when the client uses standard ways to request JSONP data. The callback parameter has to be made static.
This is the standard jQuery behaviour to fetch JSONP:
$.getJSON("http://YourSite/Controller/GetJSONP?callback=?")
The '?' is automaticly set to a unique value by jQuery which will result in either 2 things for a normal Cacheoutput
- Your cache is bypassed since your parameters are changing by each request
- The client breaks because the callback you return isnt the one it stated in it's URL
This is one way to fix these issues:
Instead of using $.getJSON() use $.getScript() instead. With getScript you can specify a static callback parameter.
$.getScript(" http://YourSite/Controller/GetJSONP?callback=DataDownloaded", function(data) { alert('done'); }); function DataDownloaded (data) { alert('done'); }
jQuery still adds a unique ID to the actual URL but we can work past that.
This is our method in our controller:
[OutputCache(Duration = 60*30 /* 30mins */, VaryByParam = "callback")] public JsonpResult GetJSONP(String _, String callback) { //Your code here }It takes 2 parameters. '_' is generated by jQuery as a unique id. Callback is what we manually set to a static value.
I then added the OutputCache annotation, set the duration to 30 minutes and set it to vary only by "callback".
The result is a cache is built for every unique callback parameter, but jquerys '_' parameter is ignored.
Our result is a slender, fast and working cache that works with JSONP
Update 4/4-2012.
Another way to aproach the problem is to deal with it clientside. By using jQuery.ajax and it's cache setting you can remove the timestamp property alltogether.
cacheBoolean
Default: true, false for dataType 'script' and 'jsonp'
If set to
More info here: http://api.jquery.com/jQuery.ajax/false
, it will force requested pages not to be cached by the browser. Setting cache to false
also appends a query string parameter, "_=[TIMESTAMP]", to the URL.Thank you Marc Brooks for this information
You can make newer versions of jQuery allow caching by setting the cache option on the request to true. This will prevent jQuery from adding the _=[TIMESTAMP] parameter (which is there just to bust caches)
SvarSlethttp://api.jquery.com/jQuery.ajax/
Hi Marc, thank you for the comment. I have updated the post to reflect the "cache" setting in jQuery.
SvarSlet