ASP.NET MVC中,动态处理页面静态化 【转载】
首先解释一下什么是动态处理页面静态化
对于需要静态化的页面,第一次访问某个Action时,会先执行Action,并在页面渲染后向Response和服务器中网站的目录下都写入需要返回的html,而第二次访问此页时,在执行Action前,程序会先在指定目录下寻找是否存在当前请求对应的静态页面,如果有,则直接返回静态页面,如果没有,则按第一次访问此请求进行处理,即执行Action,并向Response和服务器中网站的目录下都写入需要返回的html。利用这种方式,可以在网站在请求的过程中,会动态的生成静态页面,而无需人工干预,方便快捷。
接下来直接上代码

/// <summary>
/// 页面静态化过滤器
/// 思路:在执行Action前,先判断此Action返回的View()的静态文件是否存在
/// 如果存在,则直接返回静态文件。
/// 如果不存在,则利用OnResultExecuting,替换Response中的输出流,让渲染后的html写入到
/// 本过滤器定义的StringBuilder中,然后在OnResultExecuted中(页面渲染后),从StringBuilder
/// 中获取html,并同时写入到静态文件和Response的内置输出流中
///
/// 注:由于我没找到直接从Response中获取输出流的html的方法,因此我这里是替换了Response中的output属性,
/// 替换后,渲染后的结果就会输出到我们自己写的StringBuilder中(此时Response中并没有html),此时在渲染后,
/// 再把StringBuilder中的html,分别写入静态文件和Response中(tw.write方法),完成此次请求。
/// </summary>
public class StaticHtmlFilter : ActionFilterAttribute
{
//用于保存渲染后的html文本
static StringBuilder sb;
//这几个Writer照着写就行了
static StringWriter sw;
static HtmlTextWriter hw;
static TextWriter tw;
//自定义的静态页面的后缀名
static string ext = ".html";
//静态页面的绝对路径(包括后缀名)
string fileName = null;
///静态页面的绝对路径(不包括后缀名)
static string path = null;
//静态文件是否存在
bool FileExists = false; /// <summary>
/// Action执行前,判断当前页面是否已经被静态化(Views路径下是否存在html文件)
/// 如果存在静态文件则直接设置filterContext的result,即返回html作为结果,而不执行Action中代码
/// 如果不存在静态页面文件,则不设置filterContext的result,此时将会执行Action中的代码
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//根据controller和action信息
string controller = filterContext.RouteData.Values["controller"].ToString();
string action = filterContext.RouteData.Values["action"].ToString();
object id=null;
//路由中是否包含可选参数id,如果有,则在文件名也要体现
if (!filterContext.RouteData.Values.TryGetValue("id", out id))
{
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views", controller, action);
fileName = string.Format("{0}{1}", path, ext);
}
else
{
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views", controller, action);
fileName = string.Format("{0}{1}{2}", path, id.ToString(),ext);
}
//拼装后缀名 FileExists = File.Exists(fileName);
//如果文件存在,直接返回结果
if (FileExists)
{
filterContext.Result = new FileContentResult(File.ReadAllBytes(fileName), "text/html; charset=utf-8");
}
}
/// <summary>
/// 执行完Action后,但渲染页面前执行此处
/// 渲染页面的意思是将cshtml中的后台代码,翻译为前台代码
///
/// </summary>
/// <param name="filterContext"></param>
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
if (!FileExists)
{
//保存html
sb = new StringBuilder();
//两个writer
sw = new StringWriter(sb);
hw = new HtmlTextWriter(sw);
//记住Response中原本输出流,用于返回本次请求的html,与下一句配合使用
//在渲染结束后,向tw内写入html内容
tw = filterContext.RequestContext.HttpContext.Response.Output;
//过滤器自己输出流,用于获取渲染后的html内容
filterContext.RequestContext.HttpContext.Response.Output = hw;
} }
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
//如果是静态文件不存在
if (!FileExists)
{
//获取渲染后的html文本
string res = sb.ToString();
//将文本写入到静态文件中
new Action(() => File.WriteAllText(fileName, res)).BeginInvoke(null, null);
//向Response的输出流中写入本次请求的html
tw.Write(sb.ToString());
}
}
}

什么样的Action适合静态化?
我认为有两种Action需要使用静态化
1.登录页面等无需向Action中传入参数而直接返回View的Action需要静态处理。

/// <summary>
/// 登录
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[StaticHtmlFilter]
public ActionResult Login()
{ var model = new LoginDto
{
ReturnUrl = Request.QueryString["ReturnUrl"],
LoginName = "admin",
Password = "qwaszx"
};
if (User.Identity.IsAuthenticated)
{
if (model.ReturnUrl.IsNotBlank())
return Redirect(model.ReturnUrl);
return RedirectToAction("Index");
}
return View(model);
}

2.通过一个参数进行查询的Action(注意是查询,非编辑)

/// <summary>
/// 编辑
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[StaticHtmlFilter]
public async Task<ActionResult> Edit(string id)
{
var model = await _menuService.Find(id);
return View(model);
}

注意事项
对于经常需要编辑的内容的查询页面,如商品列表如使用动态处理静态化页面,则应在编辑商品信息后,删除服务器指定目录下的静态页面,以便于页面更新。
当然我们也可以在上面的过滤器中的 OnActionExecuting 方法在判断文件是否存在时,先判断本次请求是否是编辑操作,如果是则删除相应的静态文件重新生成即可。
ASP.NET MVC中,动态处理页面静态化 【转载】的更多相关文章
- ASP.NET MVC中,动态处理页面静态化
首先解释一下什么是动态处理页面静态化 对于需要静态化的页面,第一次访问某个Action时,会先执行Action,并在页面渲染后向Response和服务器中网站的目录下都写入需要返回的html,而第二次 ...
- C# MVC 用户登录状态判断 【C#】list 去重(转载) js 日期格式转换(转载) C#日期转换(转载) Nullable<System.DateTime>日期格式转换 (转载) Asp.Net MVC中Action跳转(转载)
C# MVC 用户登录状态判断 来源:https://www.cnblogs.com/cherryzhou/p/4978342.html 在Filters文件夹下添加一个类Authenticati ...
- windows server 证书的颁发与IIS证书的使用 Dapper入门使用,代替你的DbSQLhelper Asp.Net MVC中Action跳转(转载)
windows server 证书的颁发与IIS证书的使用 最近工作业务要是用服务器证书验证,在这里记录下一. 1.添加服务器角色 [证书服务] 2.一路下一步直到证书服务安装完成; 3.选择圈选 ...
- ASP.NET使用HttpHandler进行页面静态化(自动生成页面)
这次的Demo是,一个根页面,点击链接创建子页面,子页面都是一个Template页面进行替换的 一个根页面 <%@ Page Language="C#" AutoEventW ...
- Asp.Net MVC中Action跳转(转载)
首先action的跳转大致归类: 1跳转到与当前同一控制器内的action和不同控制器内的action. 2带有参数的action跳转和不带参数的action跳转. 3跳转到指定视图,不经过Contr ...
- ASP.NET MVC 页面静态化操作的思路
本文主要讲述了在asp.net mvc中,页面静态化的几种思路和方法.对于网站来说,生成纯html静态页面除了有利于seo外,还可以减轻网站的负载能力和提高网站性能.在asp.net mvc中,视图的 ...
- Asp.Net MVC页面静态化功能实现二:用递归算法来实现
上一篇提到采用IHttpModule来实现当用户访问网站的时候,通过重新定义Response.Filter来实现将返回给客户端的html代码保存,以便用户下一次访问是直接访问静态页面. Asp.Net ...
- Asp.Net MVC页面静态化功能实现一:利用IHttpModule,摒弃ResultFilter
上一篇有提到利用IHttpModule和ResultFilter实现页面静态化功能.后来经过一些改动,将ResultFilter中要实现的功能全部转移到IHttpModule中来实现 Asp.Net ...
- Asp.Net MVC页面静态化功能实现一:利用IHttpModule和ResultFilter
由于公司现在所采用的是一套CMS内容管理系统的框架,所以最近项目中有一个需求提到要求实现页面静态化的功能.在网上查询了一些资料和文献,最后采用的是小尾鱼的池塘提供的 利用ResultFilter实现a ...
随机推荐
- ecplise导入项目报错而文件不报错
第一步 确认项目的jdk和tomcat版本,在Java Build Path的Libraries中查看包是否有报错,按照本机环境进行配置 第二步 检查 Java Compiler中的jdk版本,和ec ...
- 获取百度地图POI数据二(准备搜索关键词)
上篇讲到 想要获取尽可能多的POI数据 需要准备尽可能多的搜索关键字 那么这些关键字如何得来呢? 本人使用的方法是通过一些网站来获取这些关键词 http://poi.mapbar.com ...
- struts校验
Struts2 校验框架 Struts2 和Struts1同样也提供了校验框架,但在Struts2 已经不再把校验框架做为一个插件,而是已经内置到了Struts2中,而且配置起来更为简单方便,功能也更 ...
- mysql无法安装,报 The older version of MySQL Installer - Community cannot be removed. Contact your technical support group
解决办法: C:\Users\Administrator>msiexec /i C:\Users\Administrator\Downloads\mysql-installer-web-comm ...
- DAY2:数据类型Python3.6
数字 1.int(整型) 2. long(长整型) 3.float(浮点型) 4.complex(复数) 布尔值 1.真或假 1或0表示 字符串 知识补充 字符串转二进制 mes = "北 ...
- C#获取本地磁盘信息【转载】
直接上干货简单易懂 //磁盘监控(远程/本地)//需要引用System.Management.dllpublic class RemoteMonitoring{private static str ...
- 关于手机ios和安卓和pc的点击事件的兼容
var u = navigator.userAgent, app = navigator.appVersion; var clickEvent; var isAndroid = u.indexOf(' ...
- python基础3、4---流程控制、运算符
1.for循环 和while循环 for 临时变量 in 待遍历的数据: 循环体 (循环体这里一般加break,结束循环,执行else代码) else: 循环不满足条件执行的代码 while 表达式 ...
- win10下安装mongodb
环境 :win10 mongodb-win32-x86_64-v3.4-latest.zip 1.下载地址:https://www.mongodb.com/download-center/commu ...
- 12_jvm性能优化专题1——top命令和jstack联合定位
一:异常项目构建 1.通过while死循环构造异常常见: package com.huawei.jvm; import org.springframework.stereotype.Controlle ...