• 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         } 

  • 相关阅读:
    js的原型链
    setTimeout浅析
    并行模式库PPL应用实战(一):使用task类创建并行任务
    PC客户端开发细节记录:保存GUID到VARIANT
    UWP开发细节记录:DirectX::XMMATRIX 的坑
    UWP开发细节记录:WRL::ComPtr 的坑
    UWP开发细节记录:IStream 和 IRandomAccessStream^ 以及 IMFByteStream 互转
    UWP开发细节记录:判断文件类型
    UWP开发细节记录:加载图像文件到D2D位图和D3D纹理
    基于纤程(Fiber)实现C++异步编程库(一):原理及示例
  • 原文地址:https://www.cnblogs.com/TerryLiang/p/2247196.html
Copyright © 2020-2023  润新知