本文转自: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. 基于软件开源实践(FLOSS)论共产主义的可实现性

    好久没发博客,来个狠的,我不信挨踢界有人比我更蛋疼来研究这个. 在马克思提出共产主义100多百年后,软件开发领域中出现了一种特别的生产方式:开源(FLOSS:Free/Libre and Open S ...

  2. 用css 制作三角

    html代码: <div class="div"></div> css代码: .div{ border-top:40px solid #ff0077; bo ...

  3. [js开源组件开发]table表格组件

    table表格组件 表格的渲染组件,demo请点击http://lovewebgames.com/jsmodule/table.html,git源码请点击https://github.com/tian ...

  4. Java学习心得之 Linux下搭建JavaWeb环境

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Java学习心得之 Linux下搭建JavaWeb环境 1. 前言2. Java安装3. t ...

  5. Ruby学习心得之 Linux下搭建Ruby环境

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Ruby学习心得之 Linux下搭建Ruby环境1.前言2.Linux下安装Ruby环境 一 ...

  6. 教新手一步步解决:Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to和更新gradle问题

    android studio出现问题:Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_O ...

  7. 【Android】神奇的android:clipChildren属性

    前言 前几天有在微博上推荐过一个博客,看他文章时发现了这个属性.有些属性不常用,但需要的时候非常有用,于是做了个例子,正好项目用到,与大家分享一下. 声明 欢迎转载,请注明出处! 博客园:http:/ ...

  8. Android 中MyApplication

    package liu.basedemo; import android.app.Activity; import android.app.Application; import java.lang. ...

  9. Swift (if while)

    Swift 分支 if if后的括号可以省略 if后只能接bool值 if后的大括号不能省略 let num1 = 3.0 let num2 = 4.0 let bool : Bool = true ...

  10. 传统模式下WebService与WebAPI的相同与不同

    1.WebService是利用HTTP管道实现了RPC的一种规范形式,放弃了对HTTP原生特征与语义的完备支持:而WebAPI是要保留HTTP原生特征与语义的同时实现RPC,但WebAPI的实现风格可 ...