can someone explain me how to implement caching of JsonResult
actions in MVC 5 application?
I want to use caching of some ajax
-called actions using [OutputCache()]
attribute. Some of these actions return ActionResult
with html
-content, some JsonResult
with serialized lists of {Id, Title}
pairs which I'm going to use to construct dropdown lists.
My goal is to reduce amount of DB-queries (while building ViewModels) and server requests (when using ajax-calls for it).
So, my code looks like snippets below:
[OutputCache(Duration=60*60*24)]
public async Task<ActionResult> SearchCaseOrgDialog(){
//extract data return html page
return View();
}
[OutputCache(Duration=60*60*24)]
public async Task<JsonResult> AjaxOrgDepartments(){
//query database, serialize data, return json
var result = await ctx.OrgDepartments
.Select(d => new {
Id = d.Id,
Title = d.Title }
)
.ToListAsync();
return Json(result, JsonRequestBehavior.AllowGet);
}
When I look at FireFox tools-panel I see next picture for Html
-content:
Here Firefox uses client-side cached version of ajax
-requested page.
But situation differs with json
-content:
It doesn't cache content, and seems to transfer data from server (server-side cache).
In both cases response headers look the same:
Cache-Control:"public, max-age=86400, s-maxage=0"
Content is requested using similar ajax
-calls like
$.get(url, null, function(data){
//do something with data
});
So, how do I cache json-content? what is the right way to do it, and why default approach does not work?
If you want to avoid DB queries, you should consider caching the data at server side. You can use MemoryCache class to do that.
Quick sample
public class MyLookupDataCache
{
const string categoryCacheKey = "CATEGORYLIST";
public List<string> GetCategories()
{
var cache = MemoryCache.Default;
var items = cache.Get(categoryCacheKey);
if (items != null)
{
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now.AddDays(7); //7 days
//Now query from db
List<string> newItems = repository.GetCategories();
cache.Set(categoryCacheKey, newItems, policy);
return newItems;
}
else
{
return (List<string>) items;
}
}
}
You can change the method signature to return the type you want. For simplicity, i am using List<String>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With