您的位置:首页 > 编程语言 > ASP

asp.net mvc3的静态化实现

2014-02-08 16:03 246 查看
在需要静态化处理的Controller或Action上加一个Attribute就可以。下面是我写的一个生成静态文件的ActionFilterAttribute。

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 转载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  MVC3 静态页面