asp.net mvc3的靜態化實現

靜態化處理,能夠大大提升客戶的訪問瀏覽速度,提升用戶體驗,同時也下降了服務器自己的壓力。在asp.net mvc3中,能夠相對容易地處理靜態化問題,不用過多考慮靜態網頁的同步,生成等等問題。我提供這個方法很簡單,就須要在須要靜態化處理的Controller或Action上加一個Attribute就能夠。下面是我寫的一個生成靜態文件的ActionFilterAttribute。html

   1     using System;緩存

複製代碼
  2      using System.IO;
  3      using System.Text;
  4      using System.Web;
  5      using System.Web.Mvc;
  6      using NLog;
  7 
  8      ///   <summary>
  9       ///  生成靜態文件
 10       ///   </summary>
 11     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited =  true, AllowMultiple =  true)]
 12      public  class GenerateStaticFileAttribute : ActionFilterAttribute
 13     {
 14          #region 私有屬性
 15 
 16          private  static  readonly Logger logger = LogManager.GetCurrentClassLogger();
 17 
 18          #endregion
 19 
 20          #region 公共屬性
 21 
 22          ///   <summary>
 23           ///  過時時間,以小時爲單位
 24           ///   </summary>
 25          public  int Expiration {  getset; }
 26 
 27          ///   <summary>
 28           ///  文件後綴名
 29           ///   </summary>
 30          public  string Suffix {  getset; }
 31 
 32          ///   <summary>
 33           ///  緩存目錄
 34           ///   </summary>
 35          public  string CacheDirectory {  getset; }
 36 
 37          ///   <summary>
 38           ///  指定生成的文件名
 39           ///   </summary>
 40          public  string FileName {  getset; }
 41 
 42          #endregion
 43 
 44          #region 構造函數
 45 
 46          ///   <summary>
 47           ///  默認構造函數
 48           ///   </summary>
 49          public GenerateStaticFileAttribute()
 50         {
 51             Expiration =  1;
 52             CacheDirectory = AppDomain.CurrentDomain.BaseDirectory;
 53         }
 54 
 55          #endregion
 56 
 57          #region 方法
 58 
 59          public  override  void OnResultExecuted(ResultExecutedContext filterContext)
 60         {
 61              var fileInfo = GetCacheFileInfo(filterContext);
 62 
 63              if ((fileInfo.Exists && fileInfo.CreationTime.AddHours(Expiration) < DateTime.Now) || !fileInfo.Exists)
 64             {
 65                  var deleted =  false;
 66 
 67                  try
 68                 {
 69                      if (fileInfo.Exists)
 70                     {
 71                         fileInfo.Delete();
 72                     }
 73 
 74                     deleted =  true;
 75                 }
 76                  catch (Exception ex)
 77                 {
 78                     logger.Error( " 刪除文件:{0}發生異常:{1} ", fileInfo.FullName, ex.StackTrace);
 79                 }
 80 
 81                  var created =  false;
 82 
 83                  try
 84                 {
 85                      if (!fileInfo.Directory.Exists)
 86                     {
 87                         fileInfo.Directory.Create();
 88                     }
 89 
 90                     created =  true;
 91                 }
 92                  catch (IOException ex)
 93                 {
 94                     logger.Error( " 建立目錄:{0}發生異常:{1} ", fileInfo.DirectoryName, ex.StackTrace);
 95                 }
 96 
 97                  if (deleted && created)
 98                 {
 99                     FileStream fileStream =  null;
100                     StreamWriter streamWriter =  null;
101 
102                      try
103                     {
104                          var viewResult = filterContext.Result  as ViewResult;
105                         fileStream =  new FileStream(fileInfo.FullName, FileMode.CreateNew, FileAccess.Write, FileShare.None);
106                         streamWriter =  new StreamWriter(fileStream);
107                          var viewContext =  new ViewContext(filterContext.Controller.ControllerContext, viewResult.View, viewResult.ViewData, viewResult.TempData, streamWriter);
108                         viewResult.View.Render(viewContext, streamWriter);
109                     }
110                      catch (Exception ex)
111                     {
112                         logger.Error( " 生成緩存文件:{0}發生異常:{1} ", fileInfo.FullName, ex.StackTrace);
113                     }
114                      finally
115                     {
116                          if (streamWriter !=  null)
117                         {
118                             streamWriter.Close();
119                         }
120 
121                          if (fileStream !=  null)
122                         {
123                             fileStream.Close();
124                         }
125                     }
126                 }
127             }
128         }
129 
130          ///   <summary>
131           ///  生成文件Key
132           ///   </summary>
133           ///   <param name="controllerContext"> ControllerContext </param>
134           ///   <returns> 文件Key </returns>
135          protected  virtual  string GenerateKey(ControllerContext controllerContext)
136         {
137              var url = controllerContext.HttpContext.Request.Url.ToString();
138 
139              if ( string.IsNullOrWhiteSpace(url))
140             {
141                  return  null;
142             }
143 
144              var th =  new TigerHash();
145              var data = th.ComputeHash(Encoding.Unicode.GetBytes(url));
146              var key = Convert.ToBase64String(data, Base64FormattingOptions.None);
147             key = HttpUtility.UrlEncode(key);
148 
149              return key;
150         }
151 
152          ///   <summary>
153           ///  獲取靜態的文件信息
154           ///   </summary>
155           ///   <param name="controllerContext"> ControllerContext </param>
156           ///   <returns> 緩存文件信息 </returns>
157          protected  virtual FileInfo GetCacheFileInfo(ControllerContext controllerContext)
158         {
159              var fileName =  string.Empty;
160 
161              if ( string.IsNullOrWhiteSpace(FileName))
162             {
163                  var key = GenerateKey(controllerContext);
164 
165                  if (! string.IsNullOrWhiteSpace(key))
166                 {
167                     fileName = Path.Combine(CacheDirectory,  string.IsNullOrWhiteSpace(Suffix) ? key :  string.Format( " {0}.{1} ", key, Suffix));
168                 }
169             }
170              else
171             {
172                 fileName = Path.Combine(CacheDirectory, FileName);
173             }
174 
175              return  new FileInfo(fileName);
176         }
177 
178          #endregion
179     }
複製代碼

 

若是你們對於生成的文件和目錄有特殊的要求,那能夠重寫GetCacheFileInfo方法,好比按照日期生成目錄等等更復雜的目錄和文件結構。固然以上代碼只是提供了生成靜態頁的方法,可是訪問如何解決呢? 訪問靜態文件和規則就須要在HttpApplication的Application_BeginRequest實現了。首先能夠設置須要靜態化訪問的路由地址以html結尾。下面的是一個用於首頁的靜態化訪問的實現,很簡單,固然你能夠實現比較複雜的邏輯,好比根據文件時間來判斷是否應該訪問靜態文件等等。服務器

複製代碼
 1          protected  void Application_BeginRequest( object sender, EventArgs e)
 2         {
 3             StaticContentRewrite();
 4         }
 5 
 6          ///   <summary>
 7           ///  處理靜態發佈內容
 8           ///   </summary>
 9          private  void StaticContentRewrite()
10         {
11              if (Context.Request.FilePath ==  " / " || Context.Request.FilePath.StartsWith( " /index.html ", StringComparison.OrdinalIgnoreCase))
12             {
13                  if (File.Exists(Server.MapPath( " index.html ")))
14                 {
15                     Context.RewritePath( " index.html ");
16                 }
17             }
複製代碼

18         } mvc

相關文章
相關標籤/搜索