13

您可能知道,我们在 RC1 版本的 ASP.NET MVC 中有一个名为FileResult的新ActionResult 。

使用它,您的操作方法可以动态地将图像返回到浏览器。像这样的东西:

public ActionResult DisplayPhoto(int id)
{
   Photo photo = GetPhotoFromDatabase(id);
   return File(photo.Content, photo.ContentType);
}

在 HTML 代码中,我们可以使用如下内容:

<img src="http://mysite.com/controller/DisplayPhoto/657">

由于图像是动态返回的,我们需要一种方法来缓存返回的流,这样我们就不需要再次从数据库中读取图像。我想我们可以用这样的东西来做到这一点,我不确定:

Response.StatusCode = 304;

这告诉浏览器您的缓存中已经有图像。在将 StatusCode 设置为 304 后,我只是不知道在我的操作方法中返回什么。我应该返回 null 还是什么?

4

3 回答 3

27

这个博客为我回答了这个问题;http://weblogs.asp.net/jeff/archive/2009/07/01/304-your-images-from-a-database.aspx

基本上,您需要读取请求标头,比较最后修改的日期,如果匹配则返回 304,否则返回图像(状态为 200)并适当地设置缓存标头。

来自博客的代码片段:

public ActionResult Image(int id)
{
    var image = _imageRepository.Get(id);
    if (image == null)
        throw new HttpException(404, "Image not found");
    if (!String.IsNullOrEmpty(Request.Headers["If-Modified-Since"]))
    {
        CultureInfo provider = CultureInfo.InvariantCulture;
        var lastMod = DateTime.ParseExact(Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime();
        if (lastMod == image.TimeStamp.AddMilliseconds(-image.TimeStamp.Millisecond))
        {
            Response.StatusCode = 304;
            Response.StatusDescription = "Not Modified";
            return Content(String.Empty);
        }
    }
    var stream = new MemoryStream(image.GetImage());
    Response.Cache.SetCacheability(HttpCacheability.Public);
    Response.Cache.SetLastModified(image.TimeStamp);
    return File(stream, image.MimeType);
}
于 2010-05-30T08:11:01.987 回答
9

不要将 304 与 FileResult 一起使用。从规格

304 响应不能包含消息体,因此总是由头字段之后的第一个空行终止。

从你的问题中不清楚你想做什么。服务器不知道浏览器缓存中有什么。浏览器决定了。如果您试图告诉浏览器不要在需要时重新获取图像(如果它已经有副本),请设置响应Cache-Control 标头

如果需要返回 304,请改用 EmptyResult。

于 2009-03-02T12:54:56.710 回答
0

在较新版本的 MVC 中,您最好返回一个 HttpStatusCodeResult。这样您就不需要设置 Response.StatusCode 或弄乱其他任何东西。

public ActionResult DisplayPhoto(int id)
{
    //Your code to check your cache and get the image goes here 
    //...
    if (isChanged)
    {
         return File(photo.Content, photo.ContentType);
    }
    return new HttpStatusCodeResult(HttpStatusCode.NotModified);
}
于 2014-03-31T18:51:15.463 回答