静态页的好处大家都知道,降低服务器负载,有利于搜索引擎等等,所以文章页最好能生成静态页。
之前的文章我写过,再.net core里,伪静态非常容易实现,可以点击这里查看,如果是html请求,kestrel会先去wwwroot即静态目录找,是否存在此html,如果存在,则直接输出页面,就不会再走路由,所以根据这个思路,第一次访问是访问伪静态的页面,然后控制器里生成同样路径的真实静态页,那么下次用户访问就直接访问静态页了,而且前端绑定文章的URL的话,都是同一个,对用户来说,第一次伪静态,以及之后的真静态,是没有区别的,URL都一样。好了,开始写代码。
先Startup.cs新增节点。
endpoints.MapControllerRoute("article", "article/{year}/{month}/{ID}.html",
defaults: new { Controller = "Blog", Action = "Details" },
constraints: new { ID = @"\w{24}", year = @"[\d]{4}", month = @"[\d]{2}" });
当首次访问https://www.shuanghei.com/article/2021/05/609219b696eaa61b54c193d3.html 的时候,会由Blog控制器的,Details方法接管。
public async Task<IActionResult> Details(string year, string month, string ID)
{
Article detail = new Article();
detail = await articleRepository.FindOne(ID); //从数据库里获得实体
MakeHtml(year, month, detail);//生成静态页
//第一次返回视图,之后就访问就不会再进入此控制器了
return View("~/Views/Blog/Details.cshtml", detail);
}
private async void MakeHtml(string year, string month, Article model)
{
//这步是关键,从视图页获取html代码
var viewHtml = await this.RenderViewAsync("Details", model);
//页面底部加上生成时间
viewHtml = viewHtml + $"<!--{System.DateTime.Now}-->";
var filename = model._ID + ".html";
var dir = $"/wwwroot/article/{year}/{month}/";
//保存目录
//var savepath = _hostingEnvironment.WebRootPath;
string rootPath = hostEnvironment.ContentRootPath;
var savePath = rootPath + dir;
if (!Directory.Exists(savePath))
{//不存在目录则创建该目录
Directory.CreateDirectory(savePath);
}
System.IO.File.WriteAllText(savePath + filename, viewHtml,
Encoding.GetEncoding("utf-8"));
}
是不是觉得非常的简单方便?