Last-Modified Header in MVC

.net, asp.net, asp.net-mvc, asp.net-mvc-3

Solution

The `Last-Modified` is mainly used for caching. It's sent back for resources for which you can track the modification time. The resources doesn't have to be files but anything. for instance pages which are generated from dB information where you have a `UpdatedAt` column.

Its used in combination with the `If-Modified-Since` header which each browser sends in the Request (if it has received a `Last-Modified` header previously).

How and where can I include it in MVC?

Response.AddHeader

What are the advantages of including it?

Enable fine-grained caching for pages which are dynamically generated (for instance you can use your DB field `UpdatedAt` as the last modified header).

Example

To make everything work you have to do something like this:

public class YourController : Controller
{
    public ActionResult MyPage(string id)
    {
        var entity = _db.Get(id);
        var headerValue = Request.Headers["If-Modified-Since"];
        if (headerValue != null)
        {
            var modifiedSince = DateTime.Parse(headerValue).ToLocalTime();
            if (modifiedSince >= entity.UpdatedAt)
            {
                return new HttpStatusCodeResult(304, "Page has not been modified");
            }
        }

        // page has been changed.
        // generate a view ...

        // .. and set last modified in the date format specified in the HTTP rfc.
        Response.AddHeader("Last-Modified", entity.UpdatedAt.ToUniversalTime().ToString("R"));
    }
}

You might have to specify a format in the DateTime.Parse.

References:

- HTTP status codes

- HTTP headers

Disclamer: I do not know if ASP.NET/MVC3 supports that you manage `Last-Modified` by yourself.

Update

You could create an extension method:

public static class CacheExtensions
{
    public static bool IsModified(this Controller controller, DateTime updatedAt)
    {
        var headerValue = controller.Request.Headers['If-Modified-Since'];
        if (headerValue != null)
        {
            var modifiedSince = DateTime.Parse(headerValue).ToLocalTime();
            if (modifiedSince >= updatedAt)
            {
                return false;
            }
        }

        return true;
    }

    public static ActionResult NotModified(this Controller controller)
    {
        return new HttpStatusCodeResult(304, "Page has not been modified");
    }   
}

And then use them like this:

public class YourController : Controller
{
    public ActionResult MyPage(string id)
    {
        var entity = _db.Get(id);
        if (!this.IsModified(entity.UpdatedAt))
            return this.NotModified();

        // page has been changed.
        // generate a view ...

        // .. and set last modified in the date format specified in the HTTP rfc.
        Response.AddHeader("Last-Modified", entity.UpdatedAt.ToUniversalTime().ToString("R"));
    }
}

Problem

I have recently come across the Last-Modified Header. - How and where can I include it in MVC? - What are the advantages of including it? I want an example how last modified header can be included in an mvc project, for static pages and database queries as well? Is it different from outputcache, if yes how? Basically, I want the browser to clear the cache and display the latest data or pages automatically, without the need for the user to do a refresh or clearing the cache.

Original source

Related problems