本文转自:http://www.codeproject.com/Articles/32847/ASP-NET-MVC-Dynamic-Themes

Introduction

I really needed to enable themes for my application, and I found an interesting article about it by Chris Pietschmann. In my point of view, the only problem with his approach is that you need to repeat each page for all themes. Well, I only want to create one page per theme, and have a master page and CSS files for each theme.

Using the code

For this project, I made some assumptions:

  • The master page for each theme has the name Site.Master.
  • The master page file and CSS files will be placed on a folder with the name of the theme.
  • All the theme folders will be placed in the Content folder.

The file structure will be like this:

Now, let’s write a custom View Engine that will inherit from WebFormViewEngine. This code is only a sketch of what I want to implement. For instance, I want to save the user theme selection so that, in the next login, the user has his option set.

Hide    Shrink     Copy Code
public class ThemeViewEngine : WebFormViewEngine
{
public ThemeViewEngine()
{
base.ViewLocationFormats = new string[] {
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx"
}; base.MasterLocationFormats = new string[] {
"~/Content/{2}/Site.master"
}; base.PartialViewLocationFormats = new string[] {
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx"
};
} public override ViewEngineResult FindView(ControllerContext controllerContext,
string viewName, string masterName)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
if (string.IsNullOrEmpty(viewName))
{
throw new ArgumentException("Value is required.", "viewName");
} string themeName = this.GetThemeToUse(controllerContext); string[] searchedViewLocations;
string[] searchedMasterLocations; string controllerName =
controllerContext.RouteData.GetRequiredString("controller"); string viewPath = this.GetViewPath(this.ViewLocationFormats, viewName,
controllerName, out searchedViewLocations);
string masterPath = this.GetMasterPath(this.MasterLocationFormats, viewName,
controllerName, themeName, out searchedMasterLocations); if (!(string.IsNullOrEmpty(viewPath)) &&
(!(masterPath == string.Empty) || string.IsNullOrEmpty(masterName)))
{
return new ViewEngineResult(
(this.CreateView(controllerContext, viewPath, masterPath)), this);
}
return new ViewEngineResult(
searchedViewLocations.Union<string>(searchedMasterLocations));
} public override ViewEngineResult FindPartialView(ControllerContext controllerContext,
string partialViewName)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
if (string.IsNullOrEmpty(partialViewName))
{
throw new ArgumentException("Value is required.", partialViewName);
} string themeName = this.GetThemeToUse(controllerContext); string[] searchedLocations; string controllerName = controllerContext.RouteData.GetRequiredString("controller"); string partialPath = this.GetViewPath(this.PartialViewLocationFormats,
partialViewName, controllerName, out searchedLocations); if (string.IsNullOrEmpty(partialPath))
{
return new ViewEngineResult(searchedLocations);
}
return new ViewEngineResult(this.CreatePartialView(controllerContext,
partialPath), this);
} private string GetThemeToUse(ControllerContext controllerContext)
{
if (controllerContext.HttpContext.Request.QueryString.AllKeys.Contains("theme"))
{
string themeName = controllerContext.HttpContext.Request.QueryString["theme"];
controllerContext.HttpContext.Session.Add("Theme", themeName);
}
else if (controllerContext.HttpContext.Session["Theme"] == null)
{
controllerContext.HttpContext.Session.Add("Theme", "Default");
}
return controllerContext.HttpContext.Session["Theme"].ToString();
} private string GetViewPath(string[] locations, string viewName,
string controllerName, out string[] searchedLocations)
{
string path = null; searchedLocations = new string[locations.Length]; for (int i = 0; i < locations.Length; i++)
{
path = string.Format(CultureInfo.InvariantCulture, locations[i],
new object[] { viewName, controllerName });
if (this.VirtualPathProvider.FileExists(path))
{
searchedLocations = new string[0];
return path;
}
searchedLocations[i] = path;
}
return null;
} private string GetMasterPath(string[] locations, string viewName,
string controllerName, string themeName, out string[] searchedLocations)
{
string path = null; searchedLocations = new string[locations.Length]; for (int i = 0; i < locations.Length; i++)
{
path = string.Format(CultureInfo.InvariantCulture, locations[i],
new object[] { viewName, controllerName, themeName });
if (this.VirtualPathProvider.FileExists(path))
{
searchedLocations = new string[0];
return path;
}
searchedLocations[i] = path;
}
return null;
}
}

To finish this sample, just change the global.asax, removing all engines from the View Engine and adding the custom one:

Hide    Copy Code
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes); ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new ThemeViewEngine());
}

Well, hope that’s useful.

&amp;amp;lt;a href="http://pubads.g.doubleclick.net/gampad/jump?iu=/6839/lqm.codeproject.site/Web-Development/ASP-NET/General&amp;amp;amp;sz=300x250&amp;amp;amp;c=361649"&amp;amp;gt;&amp;amp;lt;img src="http://pubads.g.doubleclick.net/gampad/ad?iu=/6839/lqm.codeproject.site/Web-Development/ASP-NET/General&amp;amp;amp;sz=300x250&amp;amp;amp;c=361649" width="300px" height="250px" target="_blank"/&amp;amp;gt;&amp;amp;lt;/a&amp;amp;gt;

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

[转]ASP.NET MVC Dynamic Themes的更多相关文章

  1. 七天学会ASP.NET MVC(七)——创建单页应用

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

  2. 微冷的雨ASP.NET MVC之葵花宝典(MVC)

    微冷的雨ASP.NET MVC之葵花宝典 By:微冷的雨 第一章 ASP.NET MVC的请求和处理机制. 在MVC中: 01.所有的请求都要归结到控制器(Controller)上. 02.约定优于配 ...

  3. 7 天玩转 ASP.NET MVC — 第 7 天

    目录 第 1 天 第 2 天 第 3 天 第 4 天 第 5 天 第 6 天 第 7 天 0. 前言 今天是开心的一天.因为我们终于来到了系列学习的最后一节.我相信你喜欢之前的课程,并从中学到了许多. ...

  4. Bootstrap 与 ASP.NET MVC 4 不使用 NuGet Package 笔记

    转自 http://www.mytecbits.com/microsoft/dot-net/bootstrap-with-asp-net-mvc-4-step-by-step 单位最近做了一个Boot ...

  5. BrnShop开源网上商城第二讲:ASP.NET MVC框架

    在团队设计BrnShop的web项目之初,我们碰到了两个问题,第一个是数据的复用和传递,第二个是大mvc框架和小mvc框架的选择.下面我依次来说明下. 首先是数据的复用和传递:对于BrnShop的每一 ...

  6. 返璞归真 asp.net mvc (9) - asp.net mvc 3.0 新特性之 View(Razor)

    原文:返璞归真 asp.net mvc (9) - asp.net mvc 3.0 新特性之 View(Razor) [索引页][源码下载] 返璞归真 asp.net mvc (9) - asp.ne ...

  7. 【ASP.NET】第一个ASP.NET MVC应用程序

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 开发流程 新建Controller 创建Action 根据Action创建View 在Action获取数据并生产ActionResult传递 ...

  8. [转]Using the HTML5 and jQuery UI Datepicker Popup Calendar with ASP.NET MVC - Part 4

    本文转自:http://www.asp.net/mvc/overview/older-versions/using-the-html5-and-jquery-ui-datepicker-popup-c ...

  9. 七天学会ASP.NET MVC(七)——创建单页应用 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_Seven.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学 ...

随机推荐

  1. 大家一起撸代码之——Hibernate各种主键生成策略与配置详解

    1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...

  2. HBase集群安装过程中的问题集锦

    1.HRegionServer启动不正常 在namenode上执行jps,则可看到hbase启动是否正常,进程如下: [root@master bin]# jps26341 HMaster26642 ...

  3. JPA persistence

    Play provides a set of very useful helpers to simplify the management of your JPA entities. Note tha ...

  4. jPList – 实现灵活排序和分页功能的 jQuery 插件

    jPList 是一个灵活的 jQuery 插件,可以用于任何 HTML 结构的排序,分页和筛选.它支持的数据源包括:PHP + MySQL,ASP.NET + SQL Server,PHP + SQL ...

  5. 2013年最新流行的响应式 WordPress 主题【上篇】

    WordPress 是最流行的内容管理系统,经历了多年的发展和演变.它的成功体现在庞大的社区,数百万的用户,设计师和开发者推动着 WordPress 往更高的层次发展. 海量的免费主题是 WordPr ...

  6. 定制Eclipse IDE之插件篇(一)

    上文回顾:定制Eclipse IDE之功能篇(二) 在这篇文章中,我会将我定制eclipse用到的其他插件罗列出来. 一.汉化插件 Eclipse本身是英文显示的,我们能够通过插件汉化.  1. 选择 ...

  7. Nodejs学习笔记(四)--- 与MySQL交互(felixge/node-mysql)

    目录 简介和安装 测试MySQL 认识一下Connection Options MYSQL CURD 插入 更新 查询 删除 Nodejs 调用带out参数的存储过程,并得到out参数返回值 结束数据 ...

  8. H5移动端页面设计心得分享

    去年JDC出了不少优秀的武媚娘…不,H5呢,大家都很拼,同时当然也积累了一些经验和教训,今天结合咱们的实战案例,从字体,排版,动效,音效,适配性,想法这几个方面好好聊一聊关于H5的设计,希望对同学们有 ...

  9. there is no spatial analyst license available or enabled

    解决方案:右击license—属性

  10. Visual Studio 2013 的 Xamarin 安装教程

    Xamarin 配置手册和离线包下载  http://pan.baidu.com/s/1eQ3qw8a 具体操作: 安装前提条件 1. 安装Visual Studio 2013,安装过程省略,我这里安 ...