ASP.NET MVC使用SSI来实现页面静态化
页面静态化分为两种:伪静态和真静态,这里主要介绍的是真静态。
进入正题之前先简单介绍一下SSI和shtml:
1)、SSI是Server Side Include的简称(服务器端嵌入)
2)、shtml是包含有嵌入式服务器方包含命令的HTML文本。在被传送给浏览器之前,服务器会对shtml文档进行
完全的读取、分析以及修改。
想要让IIS支持服务器包含,还需要简单配制一下,打开服务器端包含即可。启用或关闭Windows功能->
Internet Information Services->万维网服务->应用程序开发功能->服务器端包含。

然后打开IIS,在主页上找到处理程序映射

你可以发现*.shtm和*.shtml的状态是已启用。

到这里,前期工作已经完成了。
来看看有那些是用了这个技术的网站:
1)、新浪网的新闻页面

2)、凤凰网的新闻页面

实现这个主要就是主要就是生成xxx.shtml文件
接下来说一下个人的想法:要生成一个shtml后缀的文件,有两方面考虑:路径和内容。
路径:{路径名}/{文件名}.shtml
路径名:随你喜欢,只要最后你能获取到这个路径就行,我是放在项目的某个文件夹下面
文件名:也是个人喜好,可以是id,可以是其他,我是用的id
内容:往指定路径的文件写东西
可以分为3步:
1)、切分:将页面切分成N个子模块,什么头啊,尾啊,导航栏啊。。。。练习的话,你想怎么分,分几个,按自己的喜好来,
实际开发要用的话,你是头就你说了算,不然就是要乖乖听话。
2)、模板:写一个页面的总模板,把切分的子模块按一定的顺序排列好,在要放title的地方写一个字符串在要放新闻内容的那一
块写一个字符串,把你觉得要动态放进页面的东西,用自己熟悉的方式在页面标志出来。就相当于mvc中的那个
@RenderBody差不多的功能,
3)、填坑:读取总模板,把那些想动态加进去的坑填补好,就可以生成一个完整的页面了。
实现如下:
切分:(我是随便切的)

模板:(主要是用了include)
<!--#include file="/Template/head_start.html"-->
<title>@title</title>
<!--#include file="/Template/head_end.html"-->
<!--#include file="/Template/body_start.html"-->
<main class="container body-content">
<div style="text-align:center;"><span>@news_title</span></div>
@news_content
</main>
<!--#include file="/Template/body_end.html"--> 填坑:(操作IO)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /// <summary> /// 生成shtml页面 /// </summary> /// <param name="newsEntity">新闻实体</param> /// <returns></returns> public static bool GenerateShtmlPage(News newsEntity) { //返回信息 string strMessage = string .Empty; //页面模板完整路径 string strTemplateFullPath = string .Format( "{0}Template/{1}" , AppDomain.CurrentDomain.BaseDirectory, "newstemplate.html" ); //保存shtml页面的绝对路径 string strStaticPageAbsolutePath = GetStaticPageAbsolutePathByNewsId(newsEntity.NewsId); //获取模板占位符数组 string [] arrPlaceholder = new string [3]; arrPlaceholder[0] = "@title" ; arrPlaceholder[1] = "@news_title" ; arrPlaceholder[2] = "@news_content" ; //获取填充到模板中的占位符所对应的数据数组 string [] arrReplaceContent = new string [3]; arrReplaceContent[0] = newsEntity.NewsTitle; arrReplaceContent[1] = newsEntity.NewsTitle; arrReplaceContent[2] = newsEntity.NewsContent; //生成shtml页面 return GenerateShtmlPage(strStaticPageAbsolutePath, strTemplateFullPath, arrPlaceholder, arrReplaceContent, out strMessage); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /// <summary> /// 根据静态的HTML页面模板生成静态页面 /// </summary> /// <param name="strStaticPageAbsolutePath">存放静态页面所在绝对路径</param> /// <param name="strTemplateAbsolutePath">静态模板页面的绝对路径</param> /// <param name="arrPlaceholder">占位符数组</param> /// <param name="arrReplaceContent">要替换的内容数组</param> /// <param name="strMessage">返回信息</param> /// <returns>生成成功返回true,失败false</returns> public static bool GenerateStaticPage( string strStaticPageAbsolutePath, string strTemplateAbsolutePath, string [] arrPlaceholder, string [] arrReplaceContent, out string strMessage) { bool isSuccess = false ; try { //生成存放静态页面目录 if (!Directory.Exists(Path.GetDirectoryName(strStaticPageAbsolutePath))) { Directory.CreateDirectory(Path.GetDirectoryName(strStaticPageAbsolutePath)); } //验证占位符 if (arrPlaceholder.Length != arrReplaceContent.Length) { strMessage = string .Format( "生成静态页面失败,占位符数组个数和替换内容个数不相等!存放路径为:{0}" , strStaticPageAbsolutePath); return false ; } //生成存放静态页面文件 if (File.Exists(strStaticPageAbsolutePath)) { File.Delete(strStaticPageAbsolutePath); } //获取模板HTML StringBuilder strHtml = new StringBuilder(); strHtml.Append(File.ReadAllText(strTemplateAbsolutePath, Encoding.UTF8)); //替换模板占位符,获取要生成的静态页面HTML for ( int i = 0; i < arrPlaceholder.Length; i++) { strHtml.Replace(arrPlaceholder[i], arrReplaceContent[i]); } //生成静态页面 File.WriteAllText(strStaticPageAbsolutePath, strHtml.ToString()); strMessage = string .Format( "生成静态页面成功!存放路径:{0}" , strStaticPageAbsolutePath); isSuccess = true ; } catch (IOException ex) { strMessage = ex.Message; isSuccess = false ; } catch (Exception ex) { strMessage = ex.Message; isSuccess = false ; } return isSuccess; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /// <summary> /// 根据新闻id生成静态页面的绝对路径 /// </summary> /// <param name="newsId">新闻id</param> /// <returns></returns> private static string GetShtmlPageAbsolutePathByNewsId( int newsId) { //静态页面名称 string strShtmlPageName = string .Format( "{0}.shtml" , newsId); //静态页面相对路径 string strShtmlPageRelativePath = string .Format( "newspage\\{0}\\{1}" , DateTime.Now.ToString( "yyyy/MM/dd" ).Replace( '/' , '\\' ), strShtmlPageName); //静态页面完整路径 string strShtmlPageAbsolutePath = AppDomain.CurrentDomain.BaseDirectory + strShtmlPageRelativePath; return strShtmlPageAbsolutePath; } |
到这里,已经生成了我们想要的xxx.shtml文件了。最后我们要做的就是访问。
假设要访问id为29的新闻,其url为:http:127.0.0.1/news/detials/29,生成的路径为/newspage/29.shtml
这可以理解为是一种映射关系。只需要修改路由,下面是我的处理方法:
添加一条路由规则:
1 2 3 4 5 | routes.MapRoute( name: "getnewspage" , url: "newspage/{id}" , defaults: new { controller = "News" , action = "Details" , id = UrlParameter.Optional } ); |
然后在News控制器中的Details正进行处理,使其访问29.shtml这个页面即可。
29.shtml中的内容如下:
访问http:127.0.0.1/News/Detials/29 时即可访问29.shtml这个文件

如果您认为这篇文章还不错或者有所收获,可以点击右下角的【推荐】按钮,因为你的支持是我继续写作,分享的最大动力!
声明:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果您发现博客中出现了错误,或者有更好的建议、想法,请及时与我联系!!如果想找我私下交流,可以私信或者加我微信。
分类:
(06)MVC
标签:
页面静态化 shtml
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述