asp.net mvc中换肤机制类库 ThemedViewEngines
制作blog系统或者通用cms系统的时候,我们经常会用到Theme功能。asp.net mvc中的一种实现方式,是继承实现RazorViewEngine即可。
这是在GitHub中找到的一个示例:https://github.com/benedict-chan/ThemedViewEngines
结构如下图:

实现的核心代码ThemedRazorViewEngine.cs:
using System;
using System.Web.Mvc; namespace ThemedViewEngines
{
public class ThemedRazorViewEngine : RazorViewEngine
{
private readonly IThemeSelectorService _themeSelectorService;
public string DefaultMasterName { get; set; }
public ThemedRazorViewEngine(IThemeSelectorService themeSelectorService)
: base()
{
DefaultMasterName = "_Layout";
this._themeSelectorService = themeSelectorService; 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", "~/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", "~/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", "~/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", "~/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", "~/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", "~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
FileExtensions = new[]
{
"cshtml",
"vbhtml",
};
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
string replacedPartialPath = GetThemedPath(partialPath);
return base.CreatePartialView(controllerContext, replacedPartialPath);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
string replacedViewPath = GetThemedPath(viewPath);
string replacedMasterPath = GetThemedPath(masterPath);
return base.CreateView(controllerContext, replacedViewPath, replacedMasterPath);
}
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
string replacedVirtualPath = GetThemedPath(virtualPath);
return base.FileExists(controllerContext, replacedVirtualPath);
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
var themeName = this._themeSelectorService.GetThemeName();
if (!string.IsNullOrEmpty(themeName) && string.IsNullOrEmpty(masterName))
{
//In case if we have a theme, and the request view is not found in the theme folder (i.e. we will use the default view),
// we will not be able to locate the theme's master page via _ViewStart (as the view is now in the default "theme" tree )
//Therefore we have to manually locate the Master page name here
masterName = DefaultMasterName;
}
return base.FindView(controllerContext, viewName, masterName, false);
}
private string GetThemedPath(string originalPath)
{
var replacedPath = originalPath;
var themeName = this._themeSelectorService.GetThemeName();
if (!string.IsNullOrEmpty(themeName))
{
string replaceText = string.Format("Themes/{0}", themeName);
replacedPath = originalPath.Replace("#@", replaceText);
}
return replacedPath;
}
}
}
ConfigThemeService.cs的代码
1 namespace ThemedViewEngines
2 {
3 public class ConfigThemeService : IThemeSelectorService
4 {
5 public string GetThemeName()
6 {
7 return ConfigurationManager.AppSettings["ThemeName"] ?? string.Empty;
8 }
9 public void SetThemeName(string themeName)
10 {
11 throw new NotSupportedException();
12 }
13
14 }
15 }
IThemeSelectorService.cs的代码:
1 namespace ThemedViewEngines
2 {
3 public interface IThemeSelectorService
4 {
5 /// <summary>
6 /// 获取Theme名称
7 /// </summary>
8 /// <returns></returns>
9 string GetThemeName();
10 /// <summary>
11 /// 设置主题名称
12 /// </summary>
13 /// <param name="themeName"></param>
14 void SetThemeName(string themeName);
15 }
16 }
CookieThemeService.cs的代码
1 using System;
2 using System.Web;
3
4 namespace ThemedViewEngines
5 {
6 public class CookieThemeService : IThemeSelectorService
7 {
8 public string GetThemeName()
9 {
10 var cookie = HttpContext.Current.Request.Cookies["ThemeName"];
11 if (cookie != null)
12 return cookie.Value;
13 return string.Empty;
14 }
15
16 public void SetThemeName(string themeName)
17 {
18 throw new System.NotImplementedException();
19 }
20 }
21 }
调用方式:
1、新建mvc项目
2、根据上图中的示例建立Themes文件夹,Themes下面新建blue和red文件夹,然后分别把Views下的文件复制到blue和red中(主要是web.config一定要复制过去,不然没有智能提示)
3、添加引用ThemedViewEngines类库
4、在global文件的Application_Start方法下添加:
1 ViewEngines.Engines.Clear();
2 //用 Web.config 配置 theme 的写法
3 ViewEngines.Engines.Add(new ThemedRazorViewEngine(new ConfigThemeService()));
4 //用cookie配置theme的写法
5 //ViewEngines.Engines.Add(new ThemedRazorViewEngine(new CookieThemeService()));
5、在Web.config的appSettings节点下添加:
<!--Theme配置-->
<add key="ThemeName" value="blue" />
<!--Theme配置 end-->
6、运行项目即可。
Demo下载
asp.net mvc中换肤机制类库 ThemedViewEngines的更多相关文章
- 转载ASP.NET MVC中Session的处理机制
本文章转载自 http://www.cnblogs.com/darrenji/p/3951065.html ASP.NET MVC中的Session以及处理方式 最近在ASP.NET MVC项目中 ...
- Asp.net Mvc中利用ValidationAttribute实现xss过滤
在网站开发中,需要注意的一个问题就是防范XSS攻击,Asp.net mvc中已经自动为我们提供了这个功能.用户提交数据时时,在生成Action参数的过程中asp.net会对用户提交的数据进行验证,一旦 ...
- 【ASP.NET MVC系列】浅谈jqGrid 在ASP.NET MVC中增删改查
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
- 如何在 ASP.NET MVC 中集成 AngularJS(1)
介绍 当涉及到计算机软件的开发时,我想运用所有的最新技术.例如,前端使用最新的 JavaScript 技术,服务器端使用最新的基于 REST 的 Web API 服务.另外,还有最新的数据库技术.最新 ...
- Asp.Net MVC中DropDownListFor的用法(转)
2016.03.04 扩展:如果 view中传入的是List<T>类型 怎么使用 DropList 既然是List<T> 那么我转化成 T List<T>的第一个 ...
- Asp.Net MVC中DropDownListFor的用法
在Asp.Net MVC中可以用DropDownListFor的方式来让用户选择已定列表中的一个数值.用法不复杂,这里简单做一个记录. 首先我们要定义一个 Model ,用户在 DropDownLis ...
- 在ASP.Net MVC 中,如何在Global.asax中配置一个指向Area内部的默认Route
ASP.Net MVC 中配置Route的时候可以设置一个默认的Route. 比如我要在输入http://localhost的时候默认进入http://localhost/home/index.可以在 ...
- 转:Asp.Net MVC中DropDownListFor的用法
在Asp.Net MVC中可以用DropDownListFor的方式来让用户选择已定列表中的一个数值.用法不复杂,这里简单做一个记录. 首先我们要定义一个 Model ,用户在 DropDownLis ...
- 在ASP.NET MVC中使用IIS级别的URL Rewrite
原文 在ASP.NET MVC中使用IIS级别的URL Rewrite 大约一年半前,我在博客上写过一系列关于URL Rewrite的文章(2.3.4),把ASP.NET平台上进行URL Rewrit ...
- ASP.NET MVC中对Model进行分步验证的解决方法
原文:ASP.NET MVC中对Model进行分步验证的解决方法 在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个 ...
随机推荐
- 好好的Typora收费了!_2022_01_20
好好的Typora收费了!_2022_01_20 用惯了Typora真的很难再去换别的MarkDown编辑工具了,导出都找不到合适的.1.0以前的不需要验证的版本直接就不能打开了,真是头大. 到处找不 ...
- Go语言基础07 _interface _1
Go语言基础07 _interface _1 与其他主要编程语⾔的差异 接⼝为⾮⼊侵性,实现不依赖于借⼝定义 所以接⼝的定义可以包含在接⼝使⽤者包内 package interface_test im ...
- UniswapV2Pair细节
UniswapV2Pair合约是Uniswap V2协议中的核心部分,用于管理流动性池.代币交换.流动性代币的铸造和销毁等操作.以下是对UniswapV2Pair合约中所有主要方法及其参数的详细讲解. ...
- BAT之shutdown命令
今天想让电脑开机后固定时间后重启,但之前只用过关机的命令,就去查询资料,并将shutdown的命令用法整体记录一下. 1 ::取消关机 2 shutdown -a 3 4 ::关机 5 shutdow ...
- 4.7 Linux压缩文件或目录中文件为.bz2格式(bzip2命令)
bzip2 命令同 gzip 命令类似,只能对文件进行压缩(或解压缩),对于目录只能压缩(或解压缩)该目录及子目录下的所有文件.当执行压缩任务完成后,会生成一个以".bz2"为后缀 ...
- Java灵魂拷问13个为什么,你都会哪些?
大家好,我是 V 哥.今天看了阿里云开发者社区关于 Java 的灵魂拷问,一线大厂在用 Java 时,都会考虑哪些问题呢,对于工作多年,又没有大厂经历的小伙伴不妨看看,V 哥总结的这13个为什么,你都 ...
- 探索 USB 上网模组,Air780ER 当仁不让
今天探索的是USB上网模组,我推荐的是Air780ER模组,本文从用户实际使用的角度,解答大家对Air780ER最关心的一些问题,内容不深入探究技术细节,更多从选型.应用等非技术维度展开. 一.Air ...
- IPC-7095E-2024 EN Design and Assembly Process Guidance for Ball Grid Arrays (BGAs). IPC-7095E BGA 设计与组装工艺的实施
IPC-7095E-2024 EN Design and Assembly Process Guidance for Ball Grid Arrays (BGAs).pdf链接: https://pa ...
- ibatis源码学习(一)整体设计和核心流程
本文主要从ibatis框架的基本代码骨架进行切入,理解ibatis框架的整体设计思路,各组件的实现细节将在后文进行分析. 背景 介绍ibatis实现之前,先来看一段jdbc代码: Class.fo ...
- python之gevent
gevent 是一个基于协程的 Python 网络库,它使用 Greenlet 库提供了一种高效的协程实现. 协程是一种轻量级的线程,允许并发执行,但没有真正的并行性.协程可 以在遇到 I/O 操作时 ...