asp.net core生成html页面

原创 Laughing  2017-12-04 20:50  阅读 142 次 评论 0 条

为了缓解服务器的压力,我们可以将一些不经常更新的页面生成html页面,然后保存到服务器,页面进行查询时,我们先查找html是否存在,如果存在,我们直接返回html页面,否则就生成对应的html页面。这里我们通过动作过滤器ActionFilterAttribute实现。

定义属性

  1. using Microsoft.AspNetCore.Mvc;  
  2. using Microsoft.AspNetCore.Mvc.Filters;  
  3. using Microsoft.AspNetCore.Mvc.Rendering;  
  4. using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;  
  5. using Microsoft.Extensions.DependencyInjection;  
  6. using Microsoft.Extensions.Options;  
  7. using System;  
  8. using System.Collections.Generic;  
  9. using System.IO;  
  10. using System.Linq;  
  11. using System.Text;  
  12. using System.Threading.Tasks;  
  13.   
  14. namespace xiangcaowuyu.net.Public.Attribute  
  15. {  
  16.     /// <summary>  
  17.     /// 实现伪静态  
  18.     /// </summary>  
  19.     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]  
  20.     public class StaticFileHandlerFilterAttribute : ActionFilterAttribute  
  21.     {  
  22.         public string Key  
  23.         {  
  24.             getset;  
  25.         }  
  26.         /// <summary>  
  27.         /// 动作执行后  
  28.         /// </summary>  
  29.         /// <param name="context"></param>  
  30.         public override void OnActionExecuted(ActionExecutedContext context)  
  31.         {  
  32.             //获取结果  
  33.             IActionResult actionResult = context.Result;  
  34.             //判断结果是否是一个ViewResult  
  35.             if (actionResult is ViewResult)  
  36.             {  
  37.                 ViewResult viewResult = actionResult as ViewResult;  
  38.                 //下面的代码就是执行这个ViewResult,并把结果的html内容放到一个StringBuiler对象中  
  39.                 var services = context.HttpContext.RequestServices;  
  40.                 var executor = services.GetRequiredService<ViewResultExecutor>();  
  41.                 var option = services.GetRequiredService<IOptions<MvcViewOptions>>();  
  42.                 var result = executor.FindView(context, viewResult);  
  43.                 result.EnsureSuccessful(originalLocations: null);  
  44.                 var view = result.View;  
  45.                 StringBuilder builder = new StringBuilder();  
  46.                 using (var writer = new StringWriter(builder))  
  47.                 {  
  48.                     var viewContext = new ViewContext(  
  49.                         context,  
  50.                         view,  
  51.                         viewResult.ViewData,  
  52.                         viewResult.TempData,  
  53.                         writer,  
  54.                         option.Value.HtmlHelperOptions);  
  55.                     view.RenderAsync(viewContext).GetAwaiter().GetResult();  
  56.                     //这句一定要调用,否则内容就会是空的  
  57.                     writer.Flush();  
  58.                 }  
  59.                 //按照规则生成静态文件名称  
  60.                 string controllerName = context.RouteData.Values["controller"].ToString().ToLower();  
  61.                 string actionName = context.RouteData.Values["action"].ToString().ToLower();  
  62.                 string id = context.RouteData.Values.ContainsKey(Key) ? context.RouteData.Values[Key].ToString() : "";  
  63.                 if (string.IsNullOrEmpty(id) && context.HttpContext.Request.Query.ContainsKey(Key))  
  64.                 {  
  65.                     id = context.HttpContext.Request.Query[Key];  
  66.                 }  
  67.                 string devicedir = Path.Combine(AppContext.BaseDirectory, "wwwroot");  
  68.                 if (!Directory.Exists(devicedir))  
  69.                 {  
  70.                     Directory.CreateDirectory(devicedir);  
  71.                 }  
  72.                 //写入文件  
  73.                 string filePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", controllerName + "-" + actionName + (string.IsNullOrEmpty(id) ? "" : ("-" + id)) + ".html");  
  74.                 using (FileStream fs = File.Open(filePath, FileMode.Create))  
  75.                 {  
  76.                     using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))  
  77.                     {  
  78.                         sw.Write(builder.ToString());  
  79.                     }  
  80.                 }  
  81.                 //输出当前的结果  
  82.                 ContentResult contentresult = new ContentResult();  
  83.                 contentresult.Content = builder.ToString();  
  84.                 contentresult.ContentType = "text/html";  
  85.                 context.Result = contentresult;  
  86.             }  
  87.         }  
  88.   
  89.         /// <summary>  
  90.         /// 动作执行前  
  91.         /// </summary>  
  92.         /// <param name="context"></param>  
  93.         public override void OnActionExecuting(ActionExecutingContext context)  
  94.         {  
  95.             //按照一定的规则生成静态文件的名称,这里是按照area+"-"+controller+"-"+action+key规则生成  
  96.             string controllerName = context.RouteData.Values["controller"].ToString().ToLower();  
  97.             string actionName = context.RouteData.Values["action"].ToString().ToLower();  
  98.             //这里的Key默认等于id,当然我们可以配置不同的Key名称  
  99.             string id = context.RouteData.Values.ContainsKey(Key) ? context.RouteData.Values[Key].ToString() : "";  
  100.             if (string.IsNullOrEmpty(id) && context.HttpContext.Request.Query.ContainsKey(Key))  
  101.             {  
  102.                 id = context.HttpContext.Request.Query[Key];  
  103.             }  
  104.             string filePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", controllerName + "-" + actionName + (string.IsNullOrEmpty(id) ? "" : ("-" + id)) + ".html");  
  105.             //判断文件是否存在  
  106.             if (File.Exists(filePath))  
  107.             {  
  108.                 FileInfo fileInfo = new FileInfo(filePath);  
  109.                 TimeSpan timeSpan = DateTime.Now - fileInfo.CreationTime;  
  110.                 if (timeSpan.TotalDays <= 1)  
  111.                 {  
  112.                     //如果存在,直接读取文件  
  113.                     using (FileStream fs = File.Open(filePath, FileMode.Open))  
  114.                     {  
  115.                         using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))  
  116.                         {  
  117.                             //通过contentresult返回文件内容  
  118.                             ContentResult contentresult = new ContentResult();  
  119.                             contentresult.Content = sr.ReadToEnd();  
  120.                             contentresult.ContentType = "text/html";  
  121.                             context.Result = contentresult;  
  122.                         }  
  123.                     }  
  124.                 }  
  125.             }  
  126.         }  
  127.     }  
  128. }  

使用

我们可以通过将属性设置到类或者方法上面来使用

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5. using Microsoft.AspNetCore.Http;  
  6. using Microsoft.AspNetCore.Mvc;  
  7. using xiangcaowuyu.net.Models.Entity;  
  8. using xiangcaowuyu.net.Public.ArticleHelper;  
  9. using xiangcaowuyu.net.Public.MenuHelper;  
  10. using Microsoft.AspNetCore.Authorization;  
  11. using xiangcaowuyu.net.Public.Attribute;  
  12.   
  13. namespace xiangcaowuyu.net.Controllers  
  14. {  
  15.     [StaticFileHandlerFilter(Key = "id")]  
  16.     public class ArticleController : BaseController  
  17.     {  
  18.         private readonly IArticleHelper articleHelper;  
  19.   
  20.         public ArticleController(IArticleHelper articleHelper, IMenuHelper menuHelper) : base(menuHelper)  
  21.         {  
  22.             this.articleHelper = articleHelper;  
  23.         }  
  24.   
  25.         // GET: Article  
  26.         public ActionResult Index()  
  27.         {  
  28.             List<Article> list = articleHelper.GetList();  
  29.             return View(list);  
  30.         }  
  31.   
  32.         // GET: Article/Details/5  
  33.         [StaticFileHandlerFilter(Key = "id")]  
  34.         public ActionResult Details(string id)  
  35.         {  
  36.             Article article = articleHelper.GetArticle(id);  
  37.             return View(article);  
  38.         }  
  39.   
  40.         // GET: Article/Create  
  41.         [Authorize(Roles = "admin")]  
  42.         public ActionResult Create()  
  43.         {  
  44.             return View();  
  45.         }  
  46.   
  47.         // POST: Article/Create  
  48.         [HttpPost]  
  49.         [ValidateAntiForgeryToken]  
  50.         [Authorize(Roles = "admin")]  
  51.         public ActionResult Create(Article article)  
  52.         {  
  53.             try  
  54.             {  
  55.                 articleHelper.InsertArticle(article);  
  56.                 return RedirectToAction(nameof(Index));  
  57.             }  
  58.             catch  
  59.             {  
  60.                 return View();  
  61.             }  
  62.         }  
  63.   
  64.         // GET: Article/Edit/5  
  65.         [Authorize(Roles = "admin")]  
  66.         public ActionResult Edit(string id)  
  67.         {  
  68.             Article article = articleHelper.GetArticle(id);  
  69.             return View(article);  
  70.         }  
  71.   
  72.         // POST: Article/Edit/5  
  73.         [HttpPost]  
  74.         [ValidateAntiForgeryToken]  
  75.         [Authorize(Roles = "admin")]  
  76.         public ActionResult Edit(string id, Article article)  
  77.         {  
  78.             try  
  79.             {  
  80.                 // TODO: Add update logic here  
  81.                 articleHelper.EditArticle(article);  
  82.                 return RedirectToAction(nameof(Index));  
  83.             }  
  84.             catch  
  85.             {  
  86.                 return View();  
  87.             }  
  88.         }  
  89.   
  90.         // GET: Article/Delete/5  
  91.         [Authorize(Roles = "admin")]  
  92.         public ActionResult Delete(string id)  
  93.         {  
  94.             if (articleHelper.DeleteArticle(id))  
  95.             {  
  96.                 ViewBag.IsDeleted = "删除成功";  
  97.             }  
  98.             else  
  99.             {  
  100.                 ViewBag.IsDeleted = "删除失败";  
  101.             }  
  102.             return View();  
  103.         }  
  104.   
  105.         // POST: Article/Delete/5  
  106.         [HttpPost]  
  107.         [ValidateAntiForgeryToken]  
  108.         [Authorize(Roles = "admin")]  
  109.         public ActionResult Delete(string id, IFormCollection collection)  
  110.         {  
  111.             try  
  112.             {  
  113.                 // TODO: Add delete logic here  
  114.   
  115.                 return RedirectToAction(nameof(Index));  
  116.             }  
  117.             catch  
  118.             {  
  119.                 return View();  
  120.             }  
  121.         }  
  122.     }  
  123. }  

查看结果

我们查看wwroot页面,可以查看生成的html页面

本文地址:https://www.lisen.me/asp-net-core-generates-html-pages.html
版权声明:本文为原创文章,版权归 木子网 所有,欢迎分享本文,转载请保留出处!

发表评论


表情