您现在的位置是:首页>博客详情

ASP.NET MVC 使用视图引擎实现页面静态化

FreshMan2019年04月14日 09:05静态模板 视图引擎 静态化713

简介本文主要分享了在ASP.NET MVC中,使用视图做为静态模板,从而对网页进行静态化操作的方法。此方法需要对MVC视图引擎的相关知识有所了解,博文中会贴出一些资料以供参考,文章也会分享演示项目的下载地址。

本文主要分享了在ASP.NET MVC中,使用视图做为静态模板,从而对网页进行静态化操作的方法。此方法需要对MVC视图引擎的相关知识有所了解,博文中会贴出一些资料以供参考,文章也会分享演示项目的下载地址。

以往常见的静态化方式是使用HTML页面作为静态化模板,但对开发人员来说将会添加额外的工作量,毕竟同时维护模板和动态页面,是十分烦人的任务。但是如果直接使用ASP.NET MVC本身的视图作为模板,由于使用了视图,开发起来将会更简单。

使用视图引擎进行静态化操作,主要使用到了两个类:ViewEngines类ViewContext类。通过ViewEngines类的FindView方法或FindPartialView方法找到要进行静态化的视图页面,然后使用ViewContext类将数据模型填充到视图模板中,获取页面内容后生成静态页面。

ViewContext类主要是封装与呈现视图相关的信息。

这里引用ASP.NET MVC 5 高级编程的相关资料:

  1. 视图引擎是一个静态的ViewEngineCollection类型对象,可以包含所有已注册的视图引擎。

  2. FindView方法迭代ViewEngineCollection中注册的视图引擎,并在每个视图引擎上调用FindView方法,并把视图名称作为参数传入。这就是ViewEngineCollection询问每个视图引擎能否渲染指定视图的方式。

  3. FindPartialView方式的工作机制与FindView几乎一样,只是它关注于查找部分视图。


演示项目下载地址见文末(项目需要使用VS2013或者更高版本的VS编译器打开)

接下来看下演示项目的大概结构:

ASP.NET MVC静态化演示项目结构图


静态化帮助类StaticPageHelper:

/*
 * 该类需要引用下列的命名空间
 * using System;
 * using System.Web;
 * using System.Text;
 * using System.IO;
 * using System.Web.Mvc;
 */
    /// <summary>
    /// 创建时间:2013-11-06
    /// 创建者:shiyousan.com
    /// 描述:静态页面生成帮助类
    /// </summary>
    public class StaticPageHelper{
    /// <summary>
    /// 根据View视图生成静态页面
    /// </summary>
    /// <param name="strStaticPageAbsolutePath">存放静态页面所在绝对路径</param>
    /// <param name="context">ControllerContext</param>
    /// <param name="strViewName">视图名称</param>
    /// <param name="strMasterName">模板视图名称</param>
    /// <param name="model">参数实体模型</param>
    /// <param name="strMessage">返回信息</param>
    /// <param name="isPartial">是否分布视图</param>
    /// <returns>生成成功返回true,失败false</returns>
    public static bool GenerateStaticPage(string strStaticPageAbsolutePath, ControllerContext context, string strViewName, string strMasterName, object model, out string strMessage, bool isPartial = false)    {        bool isSuccess = false;        try
        {            //创建存放静态页面目录                            
            if (!Directory.Exists(Path.GetDirectoryName(strStaticPageAbsolutePath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(strStaticPageAbsolutePath));
            }            //删除已有的静态页面
            if (File.Exists(strStaticPageAbsolutePath))
            {
                File.Delete(strStaticPageAbsolutePath);
            }            ViewEngineResult result = null;            if (isPartial)
            {
                result = ViewEngines.Engines.FindPartialView(context, strViewName);
            }            else
            {
                result = ViewEngines.Engines.FindView(context, strViewName, strMasterName);
            }            if (model != null)
            {
                context.Controller.ViewData.Model = model;
            }            /*
             * 设置临时数据字典作为静态化标识
             * 可以在视图上使用TempData["IsStatic"]来控制某些元素显示。
             */
            if (!context.Controller.TempData.ContainsKey("IsStatic"))
            {
                context.Controller.TempData.Add("IsStatic", true);
            }            if (result.View != null)
            {                using (var sw = new StringWriter())
                {                    string strResultHtml = string.Empty;                    //填充数据模型到视图中,并获取完整的页面
                    ViewContext viewContext = new ViewContext(context, result.View, context.Controller.ViewData, context.Controller.TempData, sw);
                    result.View.Render(viewContext, sw);
                    strResultHtml = sw.ToString();                    //通过IO操作将页面内容生成静态页面
                    File.WriteAllText(strStaticPageAbsolutePath, strResultHtml);
                    strMessage = string.Format("生成静态页面成功!存放路径:{0}", strStaticPageAbsolutePath);
                    isSuccess = true;
                }
            }            else
            {
                isSuccess = false;
                strMessage = "生成静态页面失败!未找到视图!";
            }        }        catch (IOException ex)
        {
            strMessage = ex.Message;
            isSuccess = false;
        }        catch (Exception ex)
        {
            strMessage = ex.Message;
            isSuccess = false;
        }        return isSuccess;
    }
}

 该类可帮助我们迅速的使用视图引擎进行静态化操作。


文章模型类:

public class Article{    /// <summary>
    /// 文章标题
    /// </summary>        
    public string Title { get; set; }    /// <summary>
    /// 文章内容
    /// </summary>
    public string Content { get; set; }        
    /// <summary>
    /// 文章作者 
    /// </summary>
    public string Authur { get; set; }    /// <summary>
    /// 发布日期
    /// </summary>
    public DateTime InputDate { get; set; }        
}

控制器代码:

/// <summary>/// 使用视图引擎静态化/// </summary>/// <returns></returns>[HttpPost]public ActionResult UseViewEngineStatic(){    string strMessage = string.Empty;
    Article entity = GetArticleModel(true);    //保存静态页面的绝对路径
    string strStaticPageAbsolutePath = GetStaticPageAbsolutePath();    //生成静态页面,其中的Article是视图名称
    StaticPageHelper.GenerateStaticPage(strStaticPageAbsolutePath, ControllerContext, "Article", null, entity, out strMessage);    return Content("使用视图引擎实现页面静态化-----"+strMessage);
}/// <summary>/// 文章内容展示页/// </summary>/// <returns></returns>public ActionResult Article(){
    Article entity = GetArticleModel();                        
    return View(entity);
}#region 自定义方法/// <summary>/// 获取文章数据模型,一般是要从数据库查询/// </summary>/// <param name="isViewEngine">是否使用视图引擎</param>/// <returns></returns>private Article GetArticleModel(bool isViewEngine=false){
    Article entity = new Article();
    entity.Title = "ASP.NET MVC静态化DEMO";    if (isViewEngine)
    {
        entity.Title += "----------------使用视图引擎";
    }    else
    {
        entity.Title += "----------------使用HTML模板";
    }
    entity.Authur = "十有三";
    entity.InputDate = DateTime.Now;
    entity.Content = "<p>分别演示了使用HTML模板和视图引擎这两种方式生成静态页面。</p>";    return entity;
}/// <summary>/// 获取保存静态页面绝对路径/// </summary>        /// <returns></returns>private string GetStaticPageAbsolutePath(){            
    //静态页面名称
    string strStaticPageName = string.Format("{0}.html", DateTime.Now.Ticks.ToString());    //静态页面相对路径
    string strStaticPageRelativePath = string.Format("article\\{0}\\{1}", DateTime.Now.ToString("yyyy/MM").Replace('/', '\\'), strStaticPageName);    //静态页面完整路径                                    
    string strStaticPageAbsolutePath = AppDomain.CurrentDomain.BaseDirectory + strStaticPageRelativePath;    return strStaticPageAbsolutePath;
}#endregion

UseViewEngineStatic操作方法主要调用静态帮助类进行静态化操作,并返回操作结果信息。

Article操作方法主要是获取文章数据模型,选择文章视图呈现页面到浏览器上。


操作界面视图代码(Home/Index.cshtml):

@Ajax.ActionLink("使用视图引擎实现页面静态化", "UseViewEngineStatic", "Home", null, new AjaxOptions() { HttpMethod = "POST", OnSuccess = "OnSuccess" }, new { @class = "btn btn-primary btn-lg" })
<div id="divMessage">
</div>
@section scripts{
    <script type="text/javascript">        function OnSuccess(message) {            var msg = "<div class=\"alert alert-info\" role=\"alert\">"+message+"</div>";
            $("#divMessage").prepend(msg);            
        }
    </script>
}

主要是向Home控制器下的UseViewEngineStatic操作方法发送一个AJAX请求,从而进行静态化操作。

PS:由于使用了Ajax.ActionLink,记得引用jquery.unobtrusive-ajax.js


文章视图模板(/Home/Article.cshtml,就是显示文章内容的视图页):

@model ASP.NET_MVC_Static_Operation.Models.Article
@{
    Layout = null;
}<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>静态模板页面</title>
</head>
<body>
    <h1>@Model.Title</h1>
    <hr />
    <div>文章作者:@Model.Authur | 发布时间: @Model.InputDate</div>
    <hr />
    <div>@Html.Raw(Model.Content)</div>
</body>
</html>

文章的视图页面,也是要进行静态化的模板。

上面的例子都是使用Razor视图引擎,asp.net mvc 3以来Razor已经成为默认的视图引擎。

下载地址:

文件名称:ASP.NET MVC Static Operation.zip

文件大小:8902KB

更新日期:2019/04/14