asp.net mvc3的静态化实现

静态化处理,可以大大提高客户的访问浏览速度,提高用户体验,同时也降低了服务器本身的压力。在asp.net mvc3中,可以相对容易地处理静态化问题,不用过多考虑静态网页的同步,生成等等问题。我提供这个方法很简单,就需要在需要静态化处理的Controller或Action上加一个Attribute就可以。下面是我写的一个生成静态文件的ActionFilterAttribute。

   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         } 

你可能感兴趣的:(asp.net)