Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How return 304 status with FileResult in ASP.NET MVC RC1

As you may know we have got a new ActionResult called FileResult in RC1 version of ASP.NET MVC.

Using that, your action methods can return image to browser dynamically. Something like this:

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

In the HTML code, we can use something like this:

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

Since the image is returned dynamically, we need a way to cache the returned stream so that we don't need to read the image again from database. I guess we can do it with something like this, I'm not sure:

Response.StatusCode = 304;

This tells the browser that you already have the image in your cache. I just don't know what to return in my action method after setting StatusCode to 304. Should I return null or something?

like image 372
B Faley Avatar asked Mar 02 '09 12:03

B Faley


People also ask

Can I return ActionResult Instead of view results?

First to Understand---ActionResult and ViewResult are basically a return type for an method(i.e Action in MVC). Second The Difference is --- ActionResult can return any type of Result Whereas ViewResult can return result type of View Only.

What is ActionResult () in MVC concrete class?

What is an ActionResult? ActionResult is an abstract class that represents the result of an action method. The class itself inherits from System. Object, and only adds one additional abstract method: ExecuteResult, which is an abstract method that the derived classes of ActionResult will implement themselves.

What is return type in ASP NET MVC?

Basic return types of actionresults in ASP.NET MVC are :- ViewResult. PartialViewResult. Contentresult. Emptyresult.


1 Answers

This blog answered the question for me; http://weblogs.asp.net/jeff/archive/2009/07/01/304-your-images-from-a-database.aspx

Basically, you need to read the request header, compare the last modified dates and return 304 if they match, otherwise return the image (with a 200 status) and set the cache headers appropriately.

Code snippet from the blog:

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);
}
like image 77
WildJoe Avatar answered Sep 21 '22 17:09

WildJoe