• italiano (Italia)
    • English (United States)
    • العربية (مصر)
    • Deutsch (Deutschland)
    • Español (España, alfabetización internacional)
    • français (France)
    • हिंदी (भारत)
    • 日本語 (日本)
    • 한국어 (대한민국)
    • Nederlands (Nederland)
    • polski (Polska)
    • русский (Россия)
    • ไทย (ไทย)
    • Türkçe (Türkiye)
    • Tiếng Việt (Việt Nam)
    • 中文(中华人民共和国)
    • 中文(香港特別行政區)
  • Login
  • Registro
DotNetAge - Mvc & jQuery CMS
Nascondere la barra laterale

How to cache files in Mvc


Background

When i enhance the dotnetage runtime preformance with OutputCache i have found the OutputCacheAttribute seems to be not work for FileResult. At last i had to use “Last-Modified” and “ETag” http header to implatment the file cache feature for MVC.

Base concepts

What is Last-Modified

When a visitor browses your website, his/her browser caches your images, html, style sheet and other files locally for better performance. If you have the so-called "Last-Modified" header set in your pages, next time when the same visitor loads your website, the server will check whether there is a change in the files since the last time they have been accessed.

If there is no change, the server will send a "304 Not Modified" reply to the browser and the information will be loaded from the local cache. If you do not update your website very often, using "Last-modified" headers can significantly increase its loading speed.
If your website is using plain HTML files, the "Last-Modified" is just the time stamp of the HTML file. If you have, however, dynamic pages that fetch data from a database for example, things are a bit more complex. The server does not know how you are generating your data or how the data can be changed from the last time it was loaded.

What is ETag

Entity tags (ETags) are a mechanism that web servers and browsers use to determine whether the component in the browser's cache matches the one on the origin server. (An "entity" is another word a "component": images, scripts, stylesheets, etc.) ETags were added to provide a mechanism for validating entities that is more flexible than the last-modified date. An ETag is a string that uniquely identifies a specific version of a component. The only format constraints are that the string be quoted. The origin server specifies the component's ETag using the ETag response header.

 HTTP/1.1 200 OK Last-Modified:Tue, 29 Mar 2011 16:08:30 GMT ETag: "s3BsVvsMdH/IZg8XrO5NchhW2qhc2ROQMQ7a1rg990c=" Content-Length: 12195

Later, if the browser has to validate a component, it uses the If-None-Match header to pass the ETag back to the origin server. If the ETags match, a 304 status code is returned reducing the response by 12195 bytes for this example.

 GET /webshared/home/images/img_websitespark_banner.jpg HTTP/1.1 Host: dotnetage.com If-Modified-Since: Tue, 29 Mar 2011 16:08:30 GMT If-None-Match: "s3BsVvsMdH/IZg8XrO5NchhW2qhc2ROQMQ7a1rg990c=" HTTP/1.1 304 Not Modified

How to use Last-Modified and ETag to enhance file preforment

best way to extend the file cache in Mvc maybe use ActionFilter, so i create a FileCacheAttribute inhert from ActionFilter to add the “Last-Modified” and “ETag” header to http response.

1:// Copyright (c) 2011 Ray Liang (https://dotnetage.com)
2:// Dual licensed under the MIT and GPL licenses:
3:/span>// http://www.opensource.org/licenses/mit-license.php
4:// http://www.gnu.org/licenses/gpl.html
5:using System;
6:using System.Collections.Generic;
7:using System.Linq;
8:using System.Web;
9:using System.Web.Mvc;
10: 
11:namespace DNA.Mvc
12:{
13: [AttributeUsage(AttributeTargets.Class | 
14: AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
15: public class FileCacheAttribute : ActionFilterAttribute
16: {
17: private int duration = 300;
18: 
19: public int Duration
20: {
21: get { return duration; }
22: set { duration = value; }
23: }
24: 
25: public override void OnActionExecuting(ActionExecutingContext filterContext)
26: {
27: var request = filterContext.RequestContext.HttpContext.Request;
28: var response = filterContext.RequestContext.HttpContext.Response;
29: if (request.Headers["If-Modified-Since"] != null && 
30:TimeSpan.FromTicks(DateTime.Now.Ticks - DateTime.Parse(request.Headers["If-Modified-Since"]).Ticks).Seconds < Duration)
31: {
32: response.Write(DateTime.Now);
33: response.StatusCode = 304;
34: response.Headers.Add("Content-Encoding", "gzip");
35: response.StatusDescription = "Not Modified";
36: }
37: else
38: {
39: base.OnActionExecuting(filterContext);
40: }
41: }
42: 
43: private void SetFileCaching(HttpResponseBase response, string fileName)
44: {
45: response.AddFileDependency(fileName);
46: response.Cache.SetETagFromFileDependencies();
47: response.Cache.SetLastModifiedFromFileDependencies();
48: response.Cache.SetCacheability(HttpCacheability.Public);
49: response.Cache.SetMaxAge(new TimeSpan(7, 0, 0, 0));
50: response.Cache.SetSlidingExpiration(true);
51: }
52: 
53: public override void OnActionExecuted(ActionExecutedContext filterContext)
54: {
55: var result = filterContext.Result as FilePathResult;
56: if (result != null)
57: {
58: if (!string.IsNullOrEmpty(result.FileName) && (System.IO.File.Exists(result.FileName)))
59: SetFileCaching(filterContext.HttpContext.Response, result.FileName);
60: }
61: base.OnActionExecuted(filterContext);
62: }
63: }
64:}

use the filecacheattribute in action:

1:[HttpGet,FileCache(duration=3600)]
2: public FileResult Getfile()
3:{
4: return File(Server.MapPath("text.jpg"));
5:}

now the fileresult can be support the cache feature.

 


    Average:4
  • Letture
    (3558)
  • Permalink
Condividere per:

Tag cloud

Anything in here will be replaced on browsers that support the canvas element