• MVC 3.5中动态页面的静态化实现


    静态化处理,可以大大提高客户的访问浏览速度,提高用户体验,同时也降低了服务器本身的压力。在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 { get; set; }

    26

    27         /// <summary>

    28         /// 文件后缀名

    29         /// </summary>

    30         public string Suffix { get; set; }

    31

    32         /// <summary>

    33         /// 缓存目录

    34         /// </summary>

    35         public string CacheDirectory { get; set; }

    36

    37         /// <summary>

    38         /// 指定生成的文件名

    39         /// </summary>

    40         public string FileName { get; set; }

    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         }

    摘自 easynet

  • 相关阅读:
    Log4J日志配置详解
    Linux:ssh端口转发详解
    Android数据存储五种方式总结
    Nginx学习记录
    简单通用JDBC辅助类封装
    PBR.理论
    PBR.工作流贴图
    不设置readable,读取图片数据
    直接打开指定的目录
    Compute Shader基础
  • 原文地址:https://www.cnblogs.com/Qiaoyq/p/2759157.html
Copyright © 2020-2023  润新知