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的配置
示例截圖:
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、專案結構
三、樣式效果