1. 程式人生 > 實用技巧 >ASP .Net Core Api生成靜態頁面的思路和方法

ASP .Net Core Api生成靜態頁面的思路和方法

ASP .Net Core Api生成靜態頁面的思路和方法

在正常網站開發中,我們經常會用到靜態頁面,尤其是針對SEO開發的網站。關於靜態頁面或者靜態的網站的優勢,想必不用贅述了。

  1. 能夠提高訪問速度,增加使用者體驗。
  2. 有利於SEO搜尋引擎收錄(有人說沒有用了,不過目前來看,還是有用的)
  3. 靜態網頁有利於網站的穩定性(避免程式出現問題,頁面無法訪問)

目錄

建立靜態模板頁(html頁面)

在Api專案檔案下建立一個Template檔案(名稱隨意),在檔案下建立一個html頁面模板。在html檔案中,在我們需要插入資料的位置,採用一個特定字串來代替該資料。使用該模板的時候,用Replace方法,將資料進行替換。模板如下所示:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    // {title} 就可以用從表單或者資料庫獲取來的Title來代替
    <title> {title} </title>
    <meta name="Generator" content="vue.netcore">
    <meta id="viewport" name="viewport"
          content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
    <meta name="Author" content="">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="Keywords" content="">
    <meta name="Description" content="">
    <style>
        body {
            position: relative;
            height: 100%;
            max-width: 880px;
            margin: 0 auto;
            padding: 15px;
        }

        .title h2 {
            text-align: center;
            font-weight: 700;
            color: #4d4f53;
            letter-spacing: 1px;
            line-height: 54px;
            padding-bottom: 8px;
            margin-bottom: 13px;
            border-bottom: 1px dashed #ccc;
        }

        .title .source {
            text-align: center;
        }

        .title .date,
        .title .author,
        .title .count {
            letter-spacing: 1px;
            margin-left: 50px;
            font-size: 14px;
            color: #8c8b8b;
        }

        #count {
            font-size: 14px;
            color: #8c8b8b;
        }

        .tm-content {
            margin-top: 40px;
            font-size: 18px;
            letter-spacing: 1px;
        }
    </style>
</head>
<body>
    <div class="title">
        <h2>
            {title}
        </h2>
        <div class="source">
            <span class="author">來源:vol-core</span>
            <span class="date">釋出時間:{date}</span>
            <span class="count">瀏覽次數:</span><span id="count">0</span>
        </div>
    </div>
    <div class="tm-content">
        {content}
    </div>
</body>

</html>
<script>
    var count = 0;
    window.onload = function () {
        var params = window.location.href.split("?");
        if (!params || params.length <= 1) {
            return;
        }
        params[1].split("&").forEach(function (item) {
            var query = item.split("=");
            if (query.length > 0 && query[0] == "c") {
                document.getElementById("count").innerText = (~~query[1]) + 1;
            }
        })
    }
</script>

建立基於I/O操作的幫助類。(讀寫html檔案)

關於幫助類,沒有什麼過多解釋,就是I/O讀寫檔案,直接上程式碼。

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    namespace Utilities
    {
         public class FileHelper
        {
        
            public static string ReadFile(string fullName)
            {
                //  Encoding code = Encoding.GetEncoding(); //Encoding.GetEncoding("gb2312");
                //判斷路徑是否正確,如果獲取格式不正確,先用Replace做修改
                //string temp = fullName.MapPath().ReplacePath();
                string str = "";
                if (!File.Exists(fullName))
                {
                    return str;
                }
                StreamReader sr = null;
                try
                {
                    sr = new StreamReader(fullName);
                    str = sr.ReadToEnd(); // 讀取檔案
                }
                catch { }
                sr?.Close();
                sr?.Dispose();
                return str;
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="path">路徑 </param>
            /// <param name="fileName">檔名</param>
            /// <param name="content">寫入的內容</param>
            /// <param name="appendToLast">是否將內容新增到未尾,預設不新增</param>
            public static void WriteFile(string path, string fileName, string content, bool appendToLast = false)
            {
                //判斷路徑是否正確,如果獲取格式不正確,先用Replace做修改
                //path = path.ReplacePath();
                //fileName = fileName.ReplacePath();
                if (!Directory.Exists(path))//如果不存在就建立file資料夾
                    Directory.CreateDirectory(path);

                using (FileStream stream = File.Open(path + fileName, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    byte[] by = Encoding.Default.GetBytes(content);
                    if (appendToLast)
                    {
                        stream.Position = stream.Length;
                    }
                    else
                    {
                        stream.SetLength(0);
                    }
                    stream.Write(by, 0, by.Length);
                }
            }
        }
    }

獲取資料,生成靜態頁面。(讀取模板,替換資料,輸出html頁面)

  1. 單頁面生成靜態,通過form表單獲取資料,也可根據id從資料庫中獲取
  • Controller中
        /// <summary>
        /// 生成靜態頁面
        /// </summary>
        /// <param name="news"></param>
        /// <returns></returns>
        [HttpPost, Route("createPage")]
        [ApiActionPermission("App_News", ActionPermissionOptions.Add)]
        public async Task<IActionResult> CreatePage([FromBody]App_News news)
        {
            return Json(await Service.CreatePage(news));
        }
  • Server中
//WebResponseContent 是自定義的返回值類 在文末有程式碼
 public async Task<WebResponseContent> CreatePage(App_News news)
        {
            WebResponseContent webResponseContent = WebResponseContent.Instance;
            if (news == null)
            {
                return webResponseContent.Error("未獲取到資料");
            }
            if (!await repository.ExistsAsync(x => x.Id == news.Id))
            {
                return webResponseContent.Error("請求的資料已發生變化,請重新整理頁面重新提交");
            }
            string template = FileHelper.ReadFile(@"Template\\news.html");
            if (string.IsNullOrEmpty(template))
            {
                return webResponseContent.Error("未獲取到頁面的模板,請確認模板是否存在");
            }
            string filePath;
            string fileName;
            string urlPath;
            if (!string.IsNullOrEmpty(news.DetailUrl) && news.DetailUrl.IndexOf("/") != -1 && news.DetailUrl.Split(".").Length == 2)
            {
                var file = news.DetailUrl.Split("/");
                fileName = file[file.Length - 1];
                filePath = news.DetailUrl.Replace(fileName, "");
                urlPath = filePath;
            }
            else
            {
                string day = DateTime.Now.ToString("yyyyMMdd");
                fileName = DateTime.Now.ToString("HHmmsss") + new Random().Next(1000, 9999) + ".html";
                urlPath = $"static/news/{day}/";
                filePath = urlPath.MapPath(true);
            }
            string content = template.Replace("{title}", news.Title).Replace("{date}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{content}", news.Content);
            FileHelper.WriteFile((filePath.IndexOf("wwwroot") == -1 ? "wwwroot/" : "") + filePath, fileName, content);
            //更新資料庫的url
            news.DetailUrl = $"{urlPath}{fileName}";
            repository.Update(news, x => new { news.DetailUrl, news.Content }, true);
            return webResponseContent.OK("面釋出成功,可預覽看效果", new { url = news.DetailUrl });
        }
  1. 多頁面批量生成
  • 獲取資料
      在前端通過複選框選中多行資料,通過非同步傳遞"id拼接字串"(如:1,2,3)。
      後臺接受字串,對字串Split(",");獲取到int[]陣列。
      通過for迴圈,建立靜態頁面。
    *生成靜態頁面
      在遍歷int[]陣列中,和生成單頁面方法一樣。

附加

  • WebResponseContent 自定義類
using VOL.Core.Enums;
using VOL.Core.Extensions;

namespace VOL.Core.Utilities
{
    public class WebResponseContent
    {
        public WebResponseContent()
        {
        }
        public WebResponseContent(bool status)
        {
            this.Status = status;
        }
        public bool Status { get; set; }
        public string Code { get; set; }
        public string Message { get; set; }
        //public string Message { get; set; }
        public object Data { get; set; }

        public WebResponseContent OK()
        {
            this.Status = true;
            return this;
        }

        public static WebResponseContent Instance
        {
            get { return new WebResponseContent(); }
        }
        public WebResponseContent OK(string message = null,object data=null)
        {
            this.Status = true;
            this.Message = message;
            this.Data = data;
            return this;
        }
        public WebResponseContent OK(ResponseType responseType)
        {
            return Set(responseType, true);
        }
        public WebResponseContent Error(string message = null)
        {
            this.Status = false;
            this.Message = message;
            return this;
        }
        public WebResponseContent Error(ResponseType responseType)
        {
            return Set(responseType, false);
        }
        public WebResponseContent Set(ResponseType responseType)
        {
            bool? b = null;
            return this.Set(responseType, b);
        }
        public WebResponseContent Set(ResponseType responseType, bool? status)
        {
            return this.Set(responseType, null, status);
        }
        public WebResponseContent Set(ResponseType responseType, string msg)
        {
            bool? b = null;
            return this.Set(responseType, msg, b);
        }
        public WebResponseContent Set(ResponseType responseType, string msg, bool? status)
        {
            if (status != null)
            {
                this.Status = (bool)status;
            }
            this.Code = ((int)responseType).ToString();
            if (!string.IsNullOrEmpty(msg))
            {
                Message = msg;
                return this;
            }
            Message = responseType.GetMsg();
            return this;
        }

    }
}