asp.net mvc3的静态化实现
2014-02-08 16:03
246 查看
在需要静态化处理的Controller或Action上加一个Attribute就可以。下面是我写的一个生成静态文件的ActionFilterAttribute。
如果大家对于生成的文件和目录有特殊的要求,那可以重写GetCacheFileInfo方法,比如按照日期生成目录等等更复杂的目录和文件结构。当然以上代码只是提供了生成静态页的方法,但是访问如何解决呢?
访问静态文件和规则就需要在HttpApplication的Application_BeginRequest实现了。首先可以设置需要静态化访问的路由地址以html结尾。下面的是一个用于首页的静态化访问的实现,很简单,当然你可以实现比较复杂的逻辑,比如根据文件时间来判断是否应该访问静态文件等等。
By:Mr.Yang 转载
using System.IO; using System.Text; using System.Web; using System.Web.Mvc; using NLog; /// <summary> /// 生成静态文件 /// </summary> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class GenerateStaticFileAttribute : ActionFilterAttribute { #region 私有属性 private static readonly Logger logger = LogManager.GetCurrentClassLogger(); #endregion #region 公共属性 /// <summary> /// 过期时间,以小时为单位 /// </summary> public int Expiration { get; set; } /// <summary> /// 文件后缀名 /// </summary> public string Suffix { get; set; } /// <summary> /// 缓存目录 /// </summary> public string CacheDirectory { get; set; } /// <summary> /// 指定生成的文件名 /// </summary> public string FileName { get; set; } #endregion #region 构造函数 /// <summary> /// 默认构造函数 /// </summary> public GenerateStaticFileAttribute() { Expiration = 1; CacheDirectory = AppDomain.CurrentDomain.BaseDirectory; } #endregion #region 方法 public override void OnResultExecuted(ResultExecutedContext filterContext) { var fileInfo = GetCacheFileInfo(filterContext); if ((fileInfo.Exists && fileInfo.CreationTime.AddHours(Expiration) < DateTime.Now) || !fileInfo.Exists) { var deleted = false; try { if (fileInfo.Exists) { fileInfo.Delete(); } deleted = true; } catch (Exception ex) { logger.Error("删除文件:{0}发生异常:{1}", fileInfo.FullName, ex.StackTrace); } var created = false; try { if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } created = true; } catch (IOException ex) { logger.Error("创建目录:{0}发生异常:{1}", fileInfo.DirectoryName, ex.StackTrace); } if (deleted && created) { FileStream fileStream = null; StreamWriter streamWriter = null; try { var viewResult = filterContext.Result as ViewResult; fileStream = new FileStream(fileInfo.FullName, FileMode.CreateNew, FileAccess.Write, FileShare.None); streamWriter = new StreamWriter(fileStream); var viewContext = new ViewContext(filterContext.Controller.ControllerContext, viewResult.View, viewResult.ViewData, viewResult.TempData, streamWriter); viewResult.View.Render(viewContext, streamWriter); } catch (Exception ex) { logger.Error("生成缓存文件:{0}发生异常:{1}", fileInfo.FullName, ex.StackTrace); } finally { if (streamWriter != null) { streamWriter.Close(); } if (fileStream != null) { fileStream.Close(); } } } } } /// <summary> /// 生成文件Key /// </summary> /// <param name="controllerContext">ControllerContext</param> /// <returns>文件Key</returns> protected virtual string GenerateKey(ControllerContext controllerContext) { var url = controllerContext.HttpContext.Request.Url.ToString(); if (string.IsNullOrWhiteSpace(url)) { return null; } var th = new TigerHash(); var data = th.ComputeHash(Encoding.Unicode.GetBytes(url)); var key = Convert.ToBase64String(data, Base64FormattingOptions.None); key = HttpUtility.UrlEncode(key); return key; } /// <summary> /// 获取静态的文件信息 /// </summary> /// <param name="controllerContext">ControllerContext</param> /// <returns>缓存文件信息</returns> protected virtual FileInfo GetCacheFileInfo(ControllerContext controllerContext) { var fileName = string.Empty; if (string.IsNullOrWhiteSpace(FileName)) { var key = GenerateKey(controllerContext); if (!string.IsNullOrWhiteSpace(key)) { fileName = Path.Combine(CacheDirectory, string.IsNullOrWhiteSpace(Suffix) ? key : string.Format("{0}.{1}", key, Suffix)); } } else { fileName = Path.Combine(CacheDirectory, FileName); } return new FileInfo(fileName); } #endregion }
如果大家对于生成的文件和目录有特殊的要求,那可以重写GetCacheFileInfo方法,比如按照日期生成目录等等更复杂的目录和文件结构。当然以上代码只是提供了生成静态页的方法,但是访问如何解决呢?
访问静态文件和规则就需要在HttpApplication的Application_BeginRequest实现了。首先可以设置需要静态化访问的路由地址以html结尾。下面的是一个用于首页的静态化访问的实现,很简单,当然你可以实现比较复杂的逻辑,比如根据文件时间来判断是否应该访问静态文件等等。
protected void Application_BeginRequest(object sender, EventArgs e) { StaticContentRewrite(); } /// <summary> /// 处理静态发布内容 /// </summary> private void StaticContentRewrite() { if (Context.Request.FilePath == "/" || Context.Request.FilePath.StartsWith("/index.html", StringComparison.OrdinalIgnoreCase)) { if (File.Exists(Server.MapPath("index.html"))) { Context.RewritePath("index.html"); } }
By:Mr.Yang 转载
相关文章推荐
- 利用ResultFilter实现asp.net mvc3 页面静态化
- 利用ResultFilter实现asp.net mvc3 页面静态化
- 利用ResultFilter实现asp.net mvc3 页面静态化
- asp.net mvc3的静态化实现
- asp.net mvc3的静态化实现
- asp.net mvc3的静态化实现
- asp.net mvc3的静态化实现1
- 利用ResultFilter实现asp.net mvc3 页面静态化
- 利用ResultFilter实现asp.net mvc3 页面静态化
- Asp.Net MVC页面静态化功能实现二:用递归算法来实现
- PHP 如何实现页面静态化?
- 用asp.net MVC3 简单实现毕业设计
- (PHP学习笔记)实现页面静态化
- 使用HttpModule实现网址重写和HttpHandler实现页面静态化冲突的解决办法
- ThinkPHP 的页面静态化功能的实现(三)
- PHP实现页面静态化
- 页面静态化实现——根据模板动态创建静态页
- ASP.NET MVC3的伪静态实现
- ASP.NET MVC3的伪静态实现代码
- PHP 实现页面静态化的几种方法