【问题标题】:ASP .Net MVC 5 JsonResult cachingASP .Net MVC 5 JsonResult 缓存
【发布时间】:2016-01-28 21:01:08
【问题描述】:

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

我的目标是减少 DB 查询(在构建 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-content 的下一张图片:

这里 Firefox 使用客户端缓存版本的 ajax-requested 页面。

但json-content 的情况有所不同:

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

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

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

使用类似的ajax-calls 来请求内容

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

那么,如何缓存 json-content?什么是正确的方法,为什么默认方法不起作用?

【问题讨论】:

  • 其他浏览器是否尊重缓存头?似乎 FF 对 AJAX 请求忽略了这一点。您还可以使用 ObjectCache (HttpContext.Current.Cache) 来存储查询的结果。
  • @Jasen,实际上当我直接在浏览器中打开链接(没有ajax)时,结果是一样的。在 Chrome 中的情况看起来也类似
  • @Edward 在那个问题中存在服务器端缓存问题。在我的情况下,服务器端缓存效果很好。客户端有问题:浏览器询问服务器并获取缓存的服务器结果,但它不使用自己的缓存

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


【解决方案1】:

如果你想避免数据库查询,你应该考虑在服务器端缓存数据。你可以使用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&lt;String&gt;

【讨论】:

    猜你喜欢
    • 2019-04-30
    • 2011-04-19
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多