分享

asp.net mvc3的静态化实现

 ThinkTank_引擎 2015-06-17

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

    9    /// 生成静态文件

    10    ///

    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        ///

    23        /// 过期时间,以小时为单位

    24        ///

    25        public int Expiration { get; set; }

    26

    27        ///

    28        /// 文件后缀名

    29        ///

    30        public string Suffix { get; set; }

    31

    32        ///

    33        /// 缓存目录

    34        ///

    35        public string CacheDirectory { get; set; }

    36

    37        ///

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

    39        ///

    40        public string FileName { get; set; }

    41

    42        #endregion

    43

    44        #region 构造函数

    45

    46        ///

    47        /// 默认构造函数

    48        ///

    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        ///

    131        /// 生成文件Key

    132        ///

    133        /// ControllerContext

    134        /// 文件Key

    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        ///

    153        /// 获取静态的文件信息

    154        ///

    155        /// ControllerContext

    156        /// 缓存文件信息

    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        ///

    7        /// 处理静态发布内容

    8        ///

    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

1 2
声明:该文章系网友上传分享,此内容仅代表网友个人经验或观点,不代表本网站立场和观点;若未进行原创声明,则表明该文章系转载自互联网;若该文章内容涉嫌侵权,请及时向上学吧网站投诉>>

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多