如何缓存将图像返回到asp.net mvc中的视图的操作方法的输出?

Posted

技术标签:

【中文标题】如何缓存将图像返回到asp.net mvc中的视图的操作方法的输出?【英文标题】:How to cache output of action method that returns image to the view in asp.net mvc? 【发布时间】:2013-02-08 09:27:48 【问题描述】:

我已经阅读了很多关于缓存的帖子,但没有一篇真正符合我的需求。在我的 mvc 3 应用程序中,我有一个返回图像类型文件的操作方法 GetImage()。然后我在视图中使用这个方法来显示图像:

<img   src="@Url.Action("GetImage", "Store", new productId = item.ProductId)"/>

我想在服务器上缓存图像。所以,我已经尝试过:

1) 使用OutputCacheAttribute:

    [HttpGet, OutputCache(Duration = 10, VaryByParam = "productId", Location = OutputCacheLocation.Server, NoStore = true)]
    public FileContentResult GetImage(int productId)
    
        var p = _productRepository.GetProduct(productId);
        if (p != null)
        
            if (System.IO.File.Exists(GetFullProductImagePath(productId)))
            
                var image = Image.FromFile(GetFullProductImagePath(productId));
                return File(GetFileContents(image), "image/jpeg");
            
        
        var defaultPath = AppDomain.CurrentDomain.BaseDirectory +
                             ConfigurationManager.AppSettings["default-images-directory"];

        var defaultImage = Image.FromFile(Path.Combine(defaultPath, "DefaultProductImage.jpg"));
        return File(GetFileContents(defaultImage), "image/jpeg");
    

图像未缓存(我得到状态:200 OK)

2) 在 GetImage() 方法中使用以下 Response.Cache 方法:

    public FileContentResult GetImage(int productId)
    
        Response.Cache.SetCacheability(HttpCacheability.Public);
        Response.Cache.SetMaxAge(new TimeSpan(0, 0, 0, 10));
        Response.Cache.SetExpires(DateTime.Now.Add(new TimeSpan(0, 0, 0, 10)));
        Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");        
        // other code is the same
    

图片不缓存

3) 在这里我得到:304 Not Modified,但 GetImage() 方法不返回任何内容(空图像)

    public FileContentResult GetImage(int productId)
    
        Response.StatusCode = 304;
        Response.StatusDescription = "Not Modified";
        Response.AddHeader("Content-Length", "0");     
        // other code is the same
    

问题:如何在服务器上缓存这个动作方法的输出?

【问题讨论】:

【参考方案1】:

试试这样:

[HttpGet]
[OutputCache(
    Duration = 10, 
    VaryByParam = "productId", 
    Location = OutputCacheLocation.ServerAndClient)]
public ActionResult GetImage(string productId)

    ...

注意事项:使用OutputCacheLocation.ServerAndClient 并摆脱NoStore = true

【讨论】:

谢谢,它运行良好!但我不明白:我不能只在服务器或客户端上单独缓存图像吗? 但是当你只在服务器上缓存图片时,这个服务器总是被命中。客户端没有缓存图像,也没有它的副本。你认为客户会从哪里得到这个图像?这就是您获得 200 状态码的原因。不同之处在于您昂贵的控制器操作不会在服务器上调用,而是直接从缓存提供给客户端。 这里需要 VaryByParam="ProductId" 吗?好像不影响结果?而且,据我所知,“ServerAndClient”意味着所有用户都将获得相同的缓存图像? 如果您希望缓存随productId 参数变化,则需要VaryByParam。缓存存储在服务器和每个客户端上,因此每个客户端都将获得相同的图像(当然会因productId 参数而异)。 如果不使用 VaryByParam 参数,用户将获得所有产品的相同图像。

以上是关于如何缓存将图像返回到asp.net mvc中的视图的操作方法的输出?的主要内容,如果未能解决你的问题,请参考以下文章

加入后将不同类型返回到视图(ASP.NET MVC2 C#)

asp.net mvc,以 JSON 形式返回多个视图

使用 ASP.NET Core MVC,如何显示图像?

ASP.Net MVC:如何显示模型中的字节数组图像

MVC asp.net 从网络文件夹加载图像

如何在 Asp.Net MVC4 Razpr 视图中将操作链接作为图像?