日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET MVC 重写RazorViewEngine实现多主题切换

發(fā)布時(shí)間:2025/4/9 asp.net 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET MVC 重写RazorViewEngine实现多主题切换 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

??? 在ASP.NET MVC中來實(shí)現(xiàn)主題的切換一般有兩種方式,一種是通過切換皮膚的css和js引用,一種就是通過重寫視圖引擎。通過重寫視圖引擎的方式更加靈活,因?yàn)槲也粌H可以在不同主題下面布局和樣式不一樣,還可以讓不同的主題下面顯示的數(shù)據(jù)條目不一致,就是說可以在某些主題下面添加一下個(gè)性化的東西。

??? 本篇我將通過重寫視圖引擎的方式來進(jìn)行演示,在這之前,我假設(shè)你已經(jīng)具備了MVC的一些基礎(chǔ),系統(tǒng)登錄后是默認(rèn)主題,當(dāng)我們點(diǎn)擊切換主題之后,左側(cè)菜單欄的布局變了,右側(cè)內(nèi)容的樣式也變了,而地址欄是不變的。界面UI用的metronic,雖然官網(wǎng)是收費(fèi)的,但是在天朝,總是可以找到免費(fèi)的。metronic是基于bootstrap的UI框架,官網(wǎng)地址:http://keenthemes.com/preview/metronic/

??? 我們先來看下效果:

??? 在這里,我使用了分區(qū)域、分模塊(按獨(dú)立的業(yè)務(wù)功能劃分)的方式,一個(gè)模塊就是一個(gè)獨(dú)立的dll,在這里Secom.Emx.Admin和Secom.Emx.History就是兩個(gè)獨(dú)立的模塊,并分別創(chuàng)建了區(qū)域Admin和History,當(dāng)然你可以在獨(dú)立模塊下面創(chuàng)建多個(gè)區(qū)域。

?

??? 你會(huì)發(fā)現(xiàn)Secom.Emx.Admin模型下面的Areas目錄和Secom.Emx.WebApp中的目錄是一模一樣的,其實(shí)我最初不想在模塊項(xiàng)目中添加任何的View,但是為了方便獨(dú)立部署還是加了。右鍵單擊項(xiàng)目Secom.Emx.Admin,選擇“屬性”——“生成事件”添加如下代碼:

xcopy /e/r/y $(ProjectDir)Areas\Admin\Views $(SolutionDir)Secom.Emx.WebApp\Areas\Admin\Views

??? 這命令很簡單,其實(shí)就是當(dāng)編譯項(xiàng)目Secom.Emx.Admin的時(shí)候,將項(xiàng)目中的Views復(fù)制到Secom.Emx.WebApp項(xiàng)目的指定目錄下。

??? 區(qū)域配置文件我放置到了Secom.Emx.WebApp中,其實(shí)你完全可以獨(dú)立放置到一個(gè)類庫項(xiàng)目中,因?yàn)樽?cè)區(qū)域路由的后,項(xiàng)目最終會(huì)尋找bin目錄下面所有繼承了AreaRegistration類的,然后讓W(xué)ebApp引用這個(gè)類庫項(xiàng)目,Secom.Emx.WebApp項(xiàng)目添加Secom.Emx.Admin、Secom.Emx.History的引用。

??? AdminAreaRegistration代碼如下:

using System.Web.Mvc;namespace Secom.Emx.WebApp {public class AdminAreaRegistration : AreaRegistration {public override string AreaName {get {return "Admin";}}public override void RegisterArea(AreaRegistrationContext context) {context.MapRoute("Admin_default","Admin/{controller}/{action}/{id}",new { action = "Index", id = UrlParameter.Optional },namespaces:new string[1] { "Secom.Emx.Admin.Areas.Admin.Controllers" });}} }

??? 注意命名空間和后面添加的 namespaces:new string[1] { "Secom.Emx.Admin.Areas.Admin.Controllers" },這個(gè)命名空間就是獨(dú)立模塊Secom.Emx.Admin下面的控制器所在的命名空間。HistoryAreaRegistration代碼如下:

using System.Web.Mvc;namespace Secom.Emx.WebApp {public class HistoryAreaRegistration : AreaRegistration {public override string AreaName {get {return "History";}}public override void RegisterArea(AreaRegistrationContext context) {context.MapRoute("History_default","History/{controller}/{action}/{id}",new { action = "Index", id = UrlParameter.Optional },namespaces:new string[1] { "Secom.Emx.History.Areas.History.Controllers" });}} } View Code

??? 我們先看下RazorViewEngine的原始構(gòu)造函數(shù)如下:

public RazorViewEngine(IViewPageActivator viewPageActivator) : base(viewPageActivator) { AreaViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.vbhtml", "~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.vbhtml" }; AreaMasterLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.vbhtml", "~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.vbhtml" }; AreaPartialViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.vbhtml", "~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.vbhtml" }; ViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; MasterLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; PartialViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; FileExtensions = new[] { "cshtml", "vbhtml", }; } View Code

??? 然后新建CustomRazorViewEngine繼承自RazorViewEngine,對(duì)View的路由規(guī)則進(jìn)行了重寫,既然可以重寫路由規(guī)則,那意味著,你可以任意定義規(guī)則,然后遵守自己定義的規(guī)則就可以了。需要注意的是,要注意路由數(shù)組中的順序,查找視圖時(shí),是按照前后順序依次查找的,當(dāng)找到了視圖就立即返回,不會(huì)再去匹配后面的路由規(guī)則。為了提升路由查找效率,我這里刪除了所有vbhtml的路由規(guī)則,因?yàn)槲艺麄€(gè)項(xiàng)目中都采用C#語言。

using System.Web.Mvc;namespace Secom.Emx.WebApp.Helper {public class CustomRazorViewEngine : RazorViewEngine{public CustomRazorViewEngine(string theme){if (!string.IsNullOrEmpty(theme)){AreaViewLocationFormats = new[]{//themes"~/themes/"+theme+"/views/Areas/{2}/{1}/{0}.cshtml","~/themes/"+theme+"/Shared/{0}.cshtml""~/Areas/{2}/Views/{1}/{0}.cshtml","~/Areas/{2}/Views/Shared/{0}.cshtml"};AreaMasterLocationFormats = new[]{//themes"~/themes/"+theme+"/views/Areas/{2}/{1}/{0}.cshtml","~/themes/"+theme+"/views/Areas/{2}/Shared/{0}.cshtml","~/themes/"+theme+"/views/Shared/{0}.cshtml","~/Areas/{2}/Views/{1}/{0}.cshtml","~/Areas/{2}/Views/Shared/{0}.cshtml"};AreaPartialViewLocationFormats = new[]{//themes"~/themes/"+theme+"/views/Shared/{0}.cshtml","~/Areas/{2}/Views/{1}/{0}.cshtml","~/Areas/{2}/Views/Shared/{0}.cshtml"};ViewLocationFormats = new[]{//themes"~/themes/"+theme+"/views/{1}/{0}.cshtml","~/Views/{1}/{0}.cshtml","~/Views/Shared/{0}.cshtml"};MasterLocationFormats = new[]{//themes"~/themes/"+theme+"/views/Shared/{0}.cshtml","~/Views/{1}/{0}.cshtml","~/Views/Shared/{0}.cshtml"};PartialViewLocationFormats = new[]{//themes"~/themes/"+theme+"/views/Shared/{0}.cshtml","~/Views/{1}/{0}.cshtml","~/Views/Shared/{0}.cshtml"};FileExtensions = new[]{"cshtml"};}}} } View Code

??? 重寫后,我們的路由規(guī)則將是這樣的:當(dāng)沒有選擇主題的情況下,沿用原來的路由規(guī)則,如果選擇了主題,則使用重寫后的路由規(guī)則。

新的路由規(guī)則:在選擇了主題的情況下,優(yōu)先查找thems/主題名稱/views/Areas/區(qū)域名稱/控制器名稱/視圖名稱.cshtml,如果找不到再按照默認(rèn)的路由規(guī)則去尋找,也就是Areas/區(qū)域名稱/Views/控制器名稱/視圖名稱.cshtml。

可以看到我們查找模板頁的方式也被修改了,所以對(duì)于一些通用的,只要換模板頁就可以了,不需要添加view界面,因?yàn)橹付ㄖ黝}下面找不到view會(huì)去默認(rèn)主題下面找,而view界面會(huì)引用模板頁的,對(duì)于一些個(gè)性化的東西,再去指定的主題下面添加新的view,不知道我這樣表述你有明白沒,感覺比較饒,反正就是你可以按照你自己的規(guī)則去找視圖,而不是asp.net mvc默認(rèn)的規(guī)則。

?

??? 切換主題View代碼:

<div class="btn-group"><button type="button" class="btn btn-circle btn-outline red dropdown-toggle" data-toggle="dropdown"><i class="fa fa-plus"></i>&nbsp;<span class="hidden-sm hidden-xs">切換主題&nbsp;</span>&nbsp;<i class="fa fa-angle-down"></i></button><ul class="dropdown-menu" role="menu"><li><a href="javascript:setTheme('default')"><i class="icon-docs"></i> 默認(rèn)主題</a></li><li><a href="javascript:setTheme('Blue')"><i class="icon-tag"></i> 藍(lán)色主題</a></li></ul></div><script type="text/javascript">function setTheme(themeName){window.location.href = "/Home/SetTheme?themeName=" + themeName + "&href=" + window.location.href;}</script>

??? 當(dāng)用戶登錄成功的時(shí)候,從Cookie中讀取所選主題信息,當(dāng)Cookie中沒有讀取到主題記錄時(shí),則從Web.config配置文件中讀取配置的主題名稱,如果都沒有讀取到,則說明是默認(rèn)主題,沿用原有的視圖引擎規(guī)則。在后臺(tái)管理界面,每次選擇了主題,我都將主題名稱存儲(chǔ)到Cookie中,默認(rèn)保存一年,這樣當(dāng)下次再登錄的時(shí)候,就能夠記住所選的主題信息了。

using System; using System.Web.Mvc; using Secom.Emx.WebApp.Helper; using System.Web; using Secom.Emx.Common.Controllers;namespace Secom.Emx.WebApp.Controllers {public class HomeController : BaseController{string themeCookieName = "Theme";public ActionResult Index(){ViewData["Menu"] = GetMenus();return View();}public ActionResult SetTheme(string themeName,string href){if (!string.IsNullOrEmpty(themeName)){Response.Cookies.Set(new HttpCookie(themeCookieName, themeName) { Expires = DateTime.Now.AddYears(1) });}else{themeName = Request.Cookies[themeCookieName].Value ?? "".Trim();}Utils.ResetRazorViewEngine(themeName);return string.IsNullOrEmpty(href)? Redirect("~/Home/Index"):Redirect(href);}public ActionResult Login(){string themeName = Request.Cookies[themeCookieName].Value ?? "".Trim();if (!string.IsNullOrEmpty(themeName)){Utils.ResetRazorViewEngine(themeName);}return View();}} }

??? Utils類:

using System.Configuration; using System.Web.Mvc;namespace Secom.Emx.WebApp.Helper {public class Utils{private static string _themeName;public static string ThemeName{get{if (!string.IsNullOrEmpty(_themeName)){return _themeName;}//模板風(fēng)格_themeName =string.IsNullOrEmpty(ConfigurationManager.AppSettings["Theme"])? "" : ConfigurationManager.AppSettings["Theme"];return _themeName;}}public static void ResetRazorViewEngine(string themeName){themeName = string.IsNullOrEmpty(themeName) ? Utils.ThemeName : themeName;if (!string.IsNullOrEmpty(themeName)){ViewEngines.Engines.Clear();ViewEngines.Engines.Add(new CustomRazorViewEngine(themeName));}}} } View Code

???? 實(shí)現(xiàn)方式實(shí)在是太簡單,簡單得我不知道如何表述才好,我還是記下來,方便有需要的人可以查閱,希望可以幫到你們。由于項(xiàng)目引入了龐大的各種相關(guān)文件以致文件比較大,網(wǎng)速原因無法上傳源碼還望見諒!

轉(zhuǎn)載于:https://www.cnblogs.com/jiekzou/p/7084827.html

總結(jié)

以上是生活随笔為你收集整理的ASP.NET MVC 重写RazorViewEngine实现多主题切换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品视频在线观看免费 | 精品欧美一区二区三区在线观看 | 熟妇高潮一区二区 | 亚洲一区视频网站 | 自拍偷拍精品视频 | 胸网站 | 影院色原网站 | 日本韩国在线播放 | 亚洲国产精品成人va在线观看 | 国产精品久久久影院 | 色综合视频在线观看 | 不卡的av在线免费观看 | 制服.丝袜.亚洲.中文.综合懂色 | 色女人综合 | 亚洲色图一区二区 | com国产| 亚洲无吗一区二区三区 | 毛片999| 久久四虎| 国产女人视频 | 老子午夜影院 | 成人做爰66片免费看网站 | 欧美日韩视频无码一区二区三 | 老熟女重囗味hdxx69 | 国产区一二三 | 久久国产经典 | 九九热视频这里只有精品 | 中文字幕毛片 | a级片在线观看视频 | 天天插夜夜| 久久久久无码精品国产sm果冻 | 亚洲成a人v | 国产精品欧美日韩 | 青春草国产视频 | 欧美一级黄视频 | 亚洲小说图片区 | 国产老妇伦国产熟女老妇视频 | 熟妇女人妻丰满少妇中文字幕 | 国产综合视频一区 | 亚洲欧美一区二区三区不卡 | 欧美成人不卡视频 | 宅男噜噜噜66一区二区 | 全程粗话对白视频videos | 91制服诱惑| 97国产精品视频人人做人人爱 | 久久精品国产一区二区电影 | av动漫免费观看 | 日韩精品无码一区二区 | 爱露出| 波多野结衣影院 | 波多野结衣电影免费观看 | 捆绑凌虐一区二区三区 | 亚洲一区h| 四季av国产一区二区三区 | 国产av无码专区亚洲av毛片搜 | 91大神小宝寻花在线观看 | 国产亚洲天堂 | 一区二区三区免费毛片 | 中文字幕免费在线观看视频 | 动漫女被黄漫免费视频 | 成人福利在线 | 97精品人妻一区二区三区香蕉 | 在线观看污视频网站 | 中文字幕丝袜 | 综合五月| 欧美日本高清视频 | 韩日欧美 | 日韩一级成人 | 啪啪网站大全 | 婷婷伊人久久 | 色窝窝无码一区二区三区 | 丰满少妇大力进入 | 一级黄色免费视频 | 桃色视屏 | 欧美国产成人精品一区二区三区 | 91麻豆国产精品 | 国产欧美久久久 | 亚洲va在线∨a天堂va欧美va | 欧美一级黄视频 | 中文字幕乱码无码人妻系列蜜桃 | 国产精品电影网站 | 污污视频网站免费观看 | 久久久久久网站 | 欧美少妇色图 | 五十路息子 | 日韩欧美一区二区三区在线观看 | 日韩av影视大全 | 91国内精品| 日日爱99| 午夜视频大全 | 日韩有码在线播放 | 免费吸乳羞羞网站视频 | 国产农村妇女毛片精品久久麻豆 | 亚洲免费视频一区 | 中文字幕人妻一区 | 国产精品v欧美精品v日韩精品 | 99福利影院 | 亚洲三级久久 | 日韩一级淫片 |