ASP.NET 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几乎一样,只是它关注于查找部分视图。

演示项目下载地址:ASP.NET MVC Static Operation.zip(项目需要使用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已经成为默认的视图引擎。




原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/98680.html

(0)
上一篇 2021年8月21日 00:53
下一篇 2021年8月21日 00:53

相关推荐

发表回复

登录后才能评论