為了提高網站性能、和網站的負載能力,頁面靜態化是一種有效的方式,這里對於asp.net mvc3 構架下的網站,提供一種個人認為比較好的靜態話方式。
實現原理是通過mvc提供的過濾器擴展點實現頁面內容的文本保存,直接上代碼:

{
public void OnResultExecuted(ResultExecutedContext filterContext)
{
}
public void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Filter = new StaticFileWriteResponseFilterWrapper(filterContext.HttpContext.Response.Filter, filterContext);
}
class StaticFileWriteResponseFilterWrapper : System.IO.Stream
{
private System.IO.Stream inner;
private ControllerContext context;
public StaticFileWriteResponseFilterWrapper(System.IO.Stream s,ControllerContext context)
{
this.inner = s;
this.context = context;
}
public override bool CanRead
{
get { return inner.CanRead; }
}
public override bool CanSeek
{
get { return inner.CanSeek; }
}
public override bool CanWrite
{
get { return inner.CanWrite; }
}
public override void Flush()
{
inner.Flush();
}
public override long Length
{
get { return inner.Length; }
}
public override long Position
{
get
{
return inner.Position;
}
set
{
inner.Position = value;
}
}
public override int Read( byte[] buffer, int offset, int count)
{
return inner.Read(buffer, offset, count);
}
public override long Seek( long offset, System.IO.SeekOrigin origin)
{
return inner.Seek(offset, origin);
}
public override void SetLength( long value)
{
inner.SetLength(value);
}
public override void Write( byte[] buffer, int offset, int count)
{
inner.Write(buffer, offset, count);
try
{
string p = context.HttpContext.Server.MapPath(HttpContext.Current.Request.Path);
if (Path.HasExtension(p))
{
string dir = Path.GetDirectoryName(p);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
if (File.Exists(p))
{
File.Delete(p);
}
File.AppendAllText(p, System.Text.Encoding.UTF8.GetString(buffer));
}
}
catch
{
}
}
}
}
我們的類StaticFileWriteFilterAttribute實現了IResultFilter,這個接口有兩個方法,OnResultExecuted和OnResultExecuting,其中OnResultExecuting是在controller中的action代碼執行完畢后,但viewresult執行之前(即頁面內容生成之前)執行;OnResultExecuted方法是在viewresult執行之后(即頁面內容生成之后)執行。
我們在頁面生成之前將StaticFileWriteResponseFilterWrapper類注冊給Response對象的Filter屬性,這里使用包裝類可以在沒有副作用的情況下注入頁面內容靜態化的代碼,對於處理業務邏輯的action是透明的。
使用方式:
全局注冊:GlobalFilters.Filters.Add(new StaticFileWriteFilterAttribute ());
單獨controller注冊
public class MyController:Controller
{
[StaticFileWriteFilter]
public ActionResult MyAction()
{
}
}
配置路由:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}.html", // URL with parameters
new { controller = "home", action = "index" } // Parameter defaults
);
例如用戶訪問http://localhost:3509/Home/About.html如果不存在此靜態文件 則訪問action,action訪問后則自動生成了此html文件,下次用戶訪問這個地址,就是訪問靜態文件了,不會進入action代碼了。