asp.net mvc中换肤机制类库 ThemedViewEngines

制作blog系统或者通用cms系统的时候,我们经常会用到Theme功能。asp.net mvc中的一种实现方式,是继承实现RazorViewEngine即可。

这是在GitHub中找到的一个示例:https://github.com/benedict-chan/ThemedViewEngines

结构如下图:

实现的核心代码ThemedRazorViewEngine.cs:


  1 using System;
  2 using System.Web.Mvc;
  3
  4 namespace ThemedViewEngines
  5 {
  6     public class ThemedRazorViewEngine : RazorViewEngine
  7     {
  8         private readonly IThemeSelectorService _themeSelectorService;
  9         public string DefaultMasterName { get; set; }
 10         public ThemedRazorViewEngine(IThemeSelectorService themeSelectorService)
 11             : base()
 12         {
 13             DefaultMasterName = "_Layout";
 14             this._themeSelectorService = themeSelectorService;
 15
 16             AreaViewLocationFormats = new[]
 17             {
 18                 "~/#@/Areas/{2}/Views/{1}/{0}.cshtml",
 19                 "~/#@/Areas/{2}/Views/{1}/{0}.vbhtml",
 20                 "~/#@/Areas/{2}/Views/Shared/{0}.cshtml",
 21                 "~/#@/Areas/{2}/Views/Shared/{0}.vbhtml",
 22
 23                 "~/Areas/{2}/Views/{1}/{0}.cshtml",
 24                 "~/Areas/{2}/Views/{1}/{0}.vbhtml",
 25                 "~/Areas/{2}/Views/Shared/{0}.cshtml",
 26                 "~/Areas/{2}/Views/Shared/{0}.vbhtml"
 27             };
 28             AreaMasterLocationFormats = new[]
 29             {
 30                 "~/#@/Areas/{2}/Views/{1}/{0}.cshtml",
 31                 "~/#@/Areas/{2}/Views/{1}/{0}.vbhtml",
 32                 "~/#@/Areas/{2}/Views/Shared/{0}.cshtml",
 33                 "~/#@/Areas/{2}/Views/Shared/{0}.vbhtml",
 34
 35                 "~/Areas/{2}/Views/{1}/{0}.cshtml",
 36                 "~/Areas/{2}/Views/{1}/{0}.vbhtml",
 37                 "~/Areas/{2}/Views/Shared/{0}.cshtml",
 38                 "~/Areas/{2}/Views/Shared/{0}.vbhtml"
 39             };
 40             AreaPartialViewLocationFormats = new[]
 41             {
 42                 "~/#@/Areas/{2}/Views/{1}/{0}.cshtml",
 43                 "~/#@/Areas/{2}/Views/{1}/{0}.vbhtml",
 44                 "~/#@/Areas/{2}/Views/Shared/{0}.cshtml",
 45                 "~/#@/Areas/{2}/Views/Shared/{0}.vbhtml",
 46
 47                 "~/Areas/{2}/Views/{1}/{0}.cshtml",
 48                 "~/Areas/{2}/Views/{1}/{0}.vbhtml",
 49                 "~/Areas/{2}/Views/Shared/{0}.cshtml",
 50                 "~/Areas/{2}/Views/Shared/{0}.vbhtml"
 51             };
 52
 53             ViewLocationFormats = new[]
 54             {
 55                 "~/#@/Views/{1}/{0}.cshtml",
 56                 "~/#@/Views/{1}/{0}.vbhtml",
 57                 "~/#@/Views/Shared/{0}.cshtml",
 58                 "~/#@/Views/Shared/{0}.vbhtml",
 59
 60                 "~/Views/{1}/{0}.cshtml",
 61                 "~/Views/{1}/{0}.vbhtml",
 62                 "~/Views/Shared/{0}.cshtml",
 63                 "~/Views/Shared/{0}.vbhtml"
 64             };
 65             MasterLocationFormats = new[]
 66             {
 67                 "~/#@/Views/{1}/{0}.cshtml",
 68                 "~/#@/Views/{1}/{0}.vbhtml",
 69                 "~/#@/Views/Shared/{0}.cshtml",
 70                 "~/#@/Views/Shared/{0}.vbhtml",
 71
 72                 "~/Views/{1}/{0}.cshtml",
 73                 "~/Views/{1}/{0}.vbhtml",
 74                 "~/Views/Shared/{0}.cshtml",
 75                 "~/Views/Shared/{0}.vbhtml"
 76             };
 77             PartialViewLocationFormats = new[]
 78             {
 79                 "~/#@/Views/{1}/{0}.cshtml",
 80                 "~/#@/Views/{1}/{0}.vbhtml",
 81                 "~/#@/Views/Shared/{0}.cshtml",
 82                 "~/#@/Views/Shared/{0}.vbhtml",
 83
 84                 "~/Views/{1}/{0}.cshtml",
 85                 "~/Views/{1}/{0}.vbhtml",
 86                 "~/Views/Shared/{0}.cshtml",
 87                 "~/Views/Shared/{0}.vbhtml"
 88             };
 89             FileExtensions = new[]
 90             {
 91                 "cshtml",
 92                 "vbhtml",
 93             };
 94         }
 95         protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
 96         {
 97             string replacedPartialPath = GetThemedPath(partialPath);
 98             return base.CreatePartialView(controllerContext, replacedPartialPath);
 99         }
100         protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
101         {
102             string replacedViewPath = GetThemedPath(viewPath);
103             string replacedMasterPath = GetThemedPath(masterPath);
104             return base.CreateView(controllerContext, replacedViewPath, replacedMasterPath);
105         }
106         protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
107         {
108             string replacedVirtualPath = GetThemedPath(virtualPath);
109             return base.FileExists(controllerContext, replacedVirtualPath);
110         }
111         public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
112         {
113             var themeName = this._themeSelectorService.GetThemeName();
114             if (!string.IsNullOrEmpty(themeName) && string.IsNullOrEmpty(masterName))
115             {
116                 //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),
117                 // we will not be able to locate the theme‘s master page via _ViewStart (as the view is now in the default "theme" tree )
118                 //Therefore we have to manually locate the Master page name here
119                 masterName = DefaultMasterName;
120             }
121             return base.FindView(controllerContext, viewName, masterName, false);
122         }
123         private string GetThemedPath(string originalPath)
124         {
125             var replacedPath = originalPath;
126             var themeName = this._themeSelectorService.GetThemeName();
127             if (!string.IsNullOrEmpty(themeName))
128             {
129                 string replaceText = string.Format("Themes/{0}", themeName);
130                 replacedPath = originalPath.Replace("#@", replaceText);
131             }
132             return replacedPath;
133         }
134     }
135 }

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下载



点击下载Demo

时间: 2024-08-01 03:03:37

asp.net mvc中换肤机制类库 ThemedViewEngines的相关文章

在ASP.NET MVC中使用NuGet添加SignalR类库之后,再次运行程序时,它出现了一个异常:

自从在ASP.NET MVC中使用NuGet添加SignalR类库之后,再次运行程序时,它出现了一个异常: Server Error in '/' Application. The following errors occurred while attempting to load the app.- No assembly found containing an OwinStartupAttribute.- No assembly found containing a Startup or [

Ioc容器Autofac系列(2)-- asp.net mvc中整合autofac(转)

经过上篇蜻蜓点水的介绍后,本篇通过实例快速上手autofac,展示当asp.net mvc引入了autofac之后会带来什么. 创建Asp.net MVC并引入Autofac 首先,创建一个MVC站点,为方便起见,选初始带HomeController和AccountController的那种.然后通过NuGet或到Autofac官网下载来引入类库.个人推荐前者,因为从VS2010开始,已内集可视化的NuGet功能,使用起来非常方便.如下图所示: 这是vs2012的界面,点击"Manage NuG

Asp.NET MVC 中使用 SignalR 实现推送功能

一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息. 可访问其官方网站:https://github.com/SignalR/ 获取更多资讯. 二.Asp.net SignalR 是个什么东东 Asp.net SignalR是微软为实现实时通信的一个类库.一般情况下,SignalR会使用JavaScript的长轮询(lo

ASP.NET MVC中使用异步控制器

线程池 一直想把项目改写成异步,但是ASP.NETMVC3下写的过于繁琐,.NET 4.5与ASP.NET MVC下代码写起来就比较简单了, MS好像也一直喜欢这样搞,每一个成熟的东西,都要演变好几个版本,才能趋于规范. ASP.NET MVC 中为什么需要使用异步呢,IIS有一个线程池来处理用户的请求,当一个新的请求过来时,将调度池中的线程以处理该请求,然而,但并发量很高的情况下,池中的线程已经不能够满足这么多的请求时候,池中的每一个线程都处于忙的状态则在处理请求时将阻塞处理请求的线程,并且该

Asp.Net MVC中DropDownListFor的用法(转)

2016.03.04 扩展:如果 view中传入的是List<T>类型 怎么使用 DropList 既然是List<T> 那么我转化成 T  List<T>的第一个,最后一个不就是M吗? @Html.DropDownListFor(model=>model.First().Title, ViewData["Title"] as List<SelectListItem>, "标题", @"dropdown

关于asp.net MVC 中的TryUpdateModel方法

有比较才会有收货,有需求才会发现更多. 在传统的WebFormk开发工作中,我们常常会存在如下的代码块 //保存 protected void btnSubmit_Click(object sender, EventArgs e) { try { BLL.MoneyBll cun = new BLL.MoneyBll(); Model.Money m1 = new Model.Money(); m1.Commany = int.Parse(this.Commany.Text); m1.Count

NHibernate中Session与ASP.NET MVC中Action的综合使用

NHibernate的基本特征是完成面向对象的程序设计语言到关系数据库的映射,在NHibernate中使用持久化对象PO(Persistent Object)完成持久化操作,对PO的操作必须在Session管理下才能同步到数据库, 但是这里的Session并非指HttpSession,可以理解为基于ADO.NET的Connnection,Session是NHibernate运作的中心,对象的生命周期.事务的管理.数据库的存取都与Session息息相关,首先,我们需要知道, SessionFact

在 asp.net mvc中的简单分页算法

//第一步:建立如下分页实体类:namespace MVCPager.Helpers { /// <summary> /// 简单分页算法类 /// </summary> public class Pager { public int RecordCount { get; set; } public int PageIndex { get; set; } public int PageSize { get; set; } public int PageCount { get { r

angular.js的路由和模板在asp.net mvc 中的使用

我们知道angular.js是基于mvc 的一款优秀js框架,它也有一套自己的路由机制,和asp.net mvc 路由不太一样.asp.net mvc 的路由是通过不同的URL到不同的controller然后交给controller去呈现视图.但是在angular.js则是需要提前指定一个module(ng-app),然后去定义路由规则,通过不同的URL,来告诉ng-app 去加载哪个页面.再渲染到ng-view.通过angular.js路由的使用,可以很容易实现页面的局部刷新.更加高效的去创建