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实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个 ...
随机推荐
- 高性能 Nginx HTTPS 调优 - 如何为 HTTPS 提速 30%
为什么要优化 Ngin HTTPS 延迟 Nginx 常作为最常见的服务器,常被用作负载均衡 (Load Balancer).反向代理 (Reverse Proxy),以及网关 (Gateway) 等 ...
- AMCL 原理解读
AMCL(adaptive Monte Carlo Localization)自适应蒙特卡洛定位,A也可以理解为augmented,,源于MCL算法的一种增强,是机器人在二维移动过程中概率定位系统,采 ...
- 使用 FastGPT 实现最佳 AI 翻译工作流:全世界最信达雅的翻译
想让AI翻译既准确又地道?本文将教你如何利用 FastGPT 打造一个革命性的翻译工作流. 它不仅支持文本翻译,还能直接处理文档,更能通过自定义术语表确保专业术语的翻译准确性,堪称翻译神器! 直接看效 ...
- esp8266 + mqtt + 温度计 (platformio)
esp8266 + mqtt + 温度计 上报温度数据 温度接线 ESP8266 温度传感器 GND GND 5V VCC A0 VOUT #include <Arduino.h> #in ...
- 异源数据同步 → DataX 同步启动后如何手动终止?
开心一刻 刚刚和老婆吵架,气到不行,想离婚女儿突然站出来劝解道:难道你们就不能打一顿孩子消消气,非要闹离婚吗?我和老婆同时看向女儿,各自挽起了衣袖女儿补充道:弟弟那么小,打他,他又不会记仇 需求背景 ...
- ElementUI Select单选切换多选无法清除历史数据的解决方案
背景: 有一个tab切换,每一个tab下都有一个 下拉框,只是一个是多选一个是单选,问题是当切换tab标签的时候,下拉框的样式不会被清空. 解决方案: 只需要在 el-select 上加一个 key ...
- 前端截图取色工具Snipaste
在Web前端开发中,在写页面CSS样式时经常要用工具去取色来设置字体颜色.背景颜色.边框颜色等等,以还原设计图的最佳效果.今天给大家推荐的取色工具是Snipaste.Snipaste 是一个简单但强大 ...
- Chrome插件之油猴(详尽版本)
官方文档: https://www.tampermonkey.net/documentation.php#google_vignette 1.注释语法: // @match https://passp ...
- MongoDB之用户管理
注意点: 验证库: 建立用户时use到的库及用户的验证库,在使用用户时,要加上验证库才能登陆. 对于管理员用户,必须在admin下创建. 1. 建用户时,use到的库,就是此用户的验证库 2. 登录时 ...
- 通过双 key 来解决缓存并发问题
我们在使用缓存的时候,不管Redis或者是Memcached,基本上都会遇到以下3个问题:缓存穿透.缓存并发.缓存集中失效.这篇文章主要针对[缓存并发]问题展开讨论,并给出具体的解决方案. 1.什么是 ...