1. 程式人生 > >ASP.NET MVC 自定義Razor檢視WorkContext

ASP.NET MVC 自定義Razor檢視WorkContext

一、實現背景

我們在使用ASP.NET MVC+Razor檢視做WEB專案的時候大家或許都有這樣的需求:

1、我們需要在每個Action中獲取一些Request請求的一些公用資訊

比如:

IsAjax 當前是否為Ajax請求

CurrentUserId 當前登入使用者Id (從Cookie中或Session中獲取)

IsSuperAdministrator 當前是否為超級管理員(拿到CurrentUserId後從DB或快取中獲取)

......

2、我們需要從後臺輸出一些公共資訊至頁面上

比如:

ResourcesVersion 資原始檔版本號

ServerDateTimeString 系統日期時間(字串型別)

 SiteTitle 站點標題

 ......

常規做法:

 接收的話我們通常會建立一個父類控制器或公共方法,來獲取或設定這些資訊

 輸出的話我們通常做法是使用 ViewBag.SiteTitle 或ViewData["SiteTitle"] 來設定與檢視的模型資料,

 然後在Razor檢視中使用@ViewBag.SiteTitle 或@ViewData["SiteTitle"] 來顯示輸出

今天我們來實踐另外一種比較簡潔的做法(個人認為比較簡潔且易擴充套件):通過自定義WebWorkContext來實踐剛才的兩點需求。建立自定義上下文和基類控制器 重寫System.Web.Mvc.WebViewPage來實踐。

二、程式實現

1、建立上下文類:WebWorkContext

namespace Mvc.WorkContext.WorkContexts
{
    public class WebWorkContext
    {
        /// <summary>
        /// 當前url
        /// </summary>
        public string Url;

        /// <summary>
        /// 當前是否為ajax請求
        /// </summary>
        public bool IsHttpAjax = false;

        /// <summary>
        /// 當前系統版本號
        /// </summary>
        public string Version = "1.0";

        /// <summary>
        /// 資原始檔版本號
        /// </summary>
        public string ResourcesVersion = "2016.07.11.01";

        /// <summary>
        /// 開始執行時間
        /// </summary>
        public DateTime StartExecuteTime;

        /// <summary>
        /// 頁面執行時長
        /// </summary>
        public double ExecuteTime;

        /// <summary>
        /// 系統日期時間(日期型別)
        /// </summary>
        public DateTime ServerDateTime = DateTime.Now;

        /// <summary>
        /// 系統日期時間(字串型別)
        /// </summary>
        public string ServerDateTimeString = "";

        /// <summary>
        /// 系統日期(字串型別)
        /// </summary>
        public string ServerDateString = "";

        /// <summary>
        /// 站點標題
        /// </summary>
        public string SiteTitle = "-";

        /// <summary>
        /// 關鍵字
        /// </summary>
        public string SiteKeywords = "";

        /// <summary>
        /// 關鍵字描述
        /// </summary>
        public string SiteDescription = "";
    }
}

備註:上下文類裡面的屬性可根據自己專案的實際情況進行刪減,比如可以新增一些當前會話相關的資訊:CurrentUserId、CurrentUserName等

2、建立BaseController

namespace Mvc.WorkContext.Controllers
{
    public class BaseController : Controller
    {
        public WebWorkContext WorkContext = new WebWorkContext();

        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            base.Initialize(requestContext);
            this.ValidateRequest = false;
            WorkContext.Url = System.Web.HttpContext.Current.Request.Url.ToString();
            if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Request != null)
            {
                WorkContext.IsHttpAjax = System.Web.HttpContext.Current.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
            }
            WorkContext.ServerDateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            WorkContext.ServerDateTimeString = WorkContext.ServerDateTime.ToString("yyyy-MM-dd HH:mm:ss");
            WorkContext.ServerDateString = WorkContext.ServerDateTime.Date.ToString("yyyy-MM-dd");
        }

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (filterContext.IsChildAction)
                return;

            if (WorkContext.IsHttpAjax)
            {

            }
            else
            {

            }
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            if (filterContext.IsChildAction)
                return;


            //頁面開始執行時間
            WorkContext.StartExecuteTime = DateTime.Now;
        }

        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);

            //頁面執行時長
            WorkContext.ExecuteTime = DateTime.Now.Subtract(WorkContext.StartExecuteTime).TotalMilliseconds / 1000;
        }
    }
}

備註: 1、 在BaseController中全域性例項WebWorkContext物件為WorkContext

2、 在BaseController裡面可在Initialize方法中對WorkContext各屬性進行賦值

3、自定義WebViewPage 繼承自System.Web.Mvc.WebViewPage

namespace Mvc.WorkContext.WebViewPages
{
    /// <summary>
    /// Razor 檢視所需的屬性和方法。
    /// </summary>
    public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
    {
        public WebWorkContext WorkContext;

        public override void InitHelpers()
        {
            base.InitHelpers();
            if (this.ViewContext.Controller is BaseController)
            {
                WorkContext = ((BaseController)(this.ViewContext.Controller)).WorkContext;
            }
        }
    }

    /// <summary>
    /// Razor 檢視所需的屬性和方法。
    /// </summary>
    public abstract class WebViewPage : WebViewPage<dynamic>
    {

    }
}

這裡重點是重寫InitHelpers方法,將BaseController中的WorkContext屬性賦值給WebViewPage中定義的WorkContext屬性

4、建立業務控制器HomeController 繼承自:BaseController

namespace Mvc.WorkContext.Controllers
{
    public class HomeController : BaseController
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            WorkContext.SiteTitle = "ASP.NET MVC 自定義Razor檢視上下文 -DEMO演示首頁";

            return View();
        }
    }
}

在各個業務控制器的Action中可以直接 Get/Set WorkContext中的屬性

5、配置View/web.config

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <!-- 
    替換原有的pageBaseType為自定義的WebViewPage
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
    -->
    <pages pageBaseType="Mvc.WorkContext.WebViewPages.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

配置Views/web.config 中的system.web.webPages.razor->pageBaseType的配置

示例截圖:

QQ截圖20171211152935.png

6、在cshtml檢視中使用WebWorkContext物件中的屬性

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>@WorkContext.SiteTitle</title>
    <meta name="keywords" content="@WorkContext.SiteKeywords" />
    <meta name="description" content="@WorkContext.SiteDescription" />
    <link href="/Content/css/[email protected]" rel="stylesheet"/>
</head>
<body>
    <h1>
        <a href="/List/Index">GOTO List</a>
    </h1>
    <table width="100%" border="0">
        <caption>@WorkContext.SiteTitle</caption>
        <tr>
            <td>序號</td>
            <td>屬性</td>
            <td>值</td>
        </tr>
        <tr>
            <td>1</td>
            <td>Url</td>
            <td>@WorkContext.Url</td>
        </tr>
        <tr>
            <td>2</td>
            <td>IsHttpAjax</td>
            <td>@WorkContext.IsHttpAjax</td>
        </tr>
        <tr>
            <td>3</td>
            <td>Version</td>
            <td>@WorkContext.Version</td>
        </tr>
        <tr>
            <td>4</td>
            <td>ResourcesVersion</td>
            <td>@WorkContext.ResourcesVersion</td>
        </tr>
        <tr>
            <td>5</td>
            <td>StartExecuteTime</td>
            <td>@WorkContext.StartExecuteTime</td>
        </tr>
        <tr>
            <td>6</td>
            <td>ExecuteTime</td>
            <td>@WorkContext.ExecuteTime</td>
        </tr>
        <tr>
            <td>7</td>
            <td>ServerDateTime</td>
            <td>@WorkContext.ServerDateTime</td>
        </tr>
        <tr>
            <td>8</td>
            <td>ServerDateTimeString</td>
            <td>@WorkContext.ServerDateTimeString</td>
        </tr>
        <tr>
            <td>9</td>
            <td>ServerDateString</td>
            <td>@WorkContext.ServerDateString</td>
        </tr>
        <tr>
            <td>10</td>
            <td>SiteTitle</td>
            <td>@WorkContext.SiteTitle</td>
        </tr>
        <tr>
            <td>11</td>
            <td>SiteKeywords</td>
            <td>@WorkContext.SiteKeywords</td>
        </tr>
        <tr>
            <td>12</td>
            <td>SiteDescription</td>
            <td>@WorkContext.SiteDescription</td>
        </tr>
    </table>

</body>
</html>

7、專案結構

QQ截圖20171211152527.png

三、樣式效果

QQ截圖20171211152641.png

QQ截圖20171211152714.png

四、程式碼截圖

image.png

注:本文著作權歸作者,由demo大師發表,拒絕轉載,轉載需要作者授權