ASP .Net MVC 5 JsonResult缓存

时间:2015-10-28 21:38:46

标签: json ajax asp.net-mvc caching asp.net-mvc-5

有人可以解释一下如何在MVC 5应用程序中实现JsonResult动作的缓存吗? 我想使用一些ajax的缓存 - 使用[OutputCache()]属性调用的操作。其中一些操作返回ActionResult html - 内容,一些JsonResult带有{Id, Title}对的序列化列表,我将用它来构建下拉列表。

我的目标是减少数据库查询(构建ViewModel时)和服务器请求(当使用ajax调用时)。

所以,我的代码看起来像下面的代码片段:

[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);
}

当我查看FireFox工具面板时,我会看到Html的下一张图片 - 内容: FF caching html content

此处Firefox使用ajax的客户端缓存版本 - 请求页面。

但情况因json而异 - 内容: FF doesn't cache json content

它不缓存内容,似乎从服务器(服务器端缓存)传输数据。

在这两种情况下,响应标题看起来都一样:

Cache-Control:"public, max-age=86400, s-maxage=0"

使用类似的ajax来调用内容 - 例如

$.get(url, null, function(data){
    //do something with data
});

那么,如何缓存json内容?什么是正确的方法,以及为什么默认方法不起作用?

2 个答案:

答案 0 :(得分:2)

如果要避免数据库查询,则应考虑在服务器端缓存数据。您可以使用MemoryCache类来执行此操作。

快速示例

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;
        }
    }
}

您可以更改方法签名以返回所需的类型。为简单起见,我使用List<String>

答案 1 :(得分:0)

我在尝试在客户端上缓存json时遇到了同样的问题,这对我有用。

提示:对于服务器端,您可以使用运行时缓存或HttpRequest.Cache

您需要使用客户端位置设置OutputCache,并使用User-Agent设置VaryByParam。

仅适用于POST,不适用于GET。

示例: Download This Solution

操作:

[OutputCache(Duration = 3600, Location = OutputCacheLocation.Client, VaryByParam = "User-Agent")]
public JsonResult ListaJson()
{

    var model = new List<string>();

    model.Add("item1");
    model.Add("item2");
    model.Add("item3");
    model.Add("item4");


    return this.Json(model, JsonRequestBehavior.AllowGet);
}

查看:

@model string

@{
    ViewBag.Title = "About";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@this.Model</h2>

<div id="id123"></div>

<script type="text/javascript">
    var url = '@Url.Action("ListaJson", "Home")';
    $(document).ready(function(){
        $("#id123").load(url);
    });
</script>

结果:

enter image description here