ASP.NET MVC:多模板支持
原文 http://www.cnblogs.com/happyframework/p/3224278.html
背景
准备写个博客练习一下WEB编程,有一个需求就是多模板支持,类似博客园的自定义模板一样,在ASP.NET MVC中如何处理这个需求呢?
需求
描述
允许自定义模板,比如:传统模板、Metro模板等
模板结构

实现思路1
重写模板引擎的默认搜索路径

private void SetTemplate(string template)
{
var razorViewEngine = ViewEngines.Engines.First(x => x is RazorViewEngine) as RazorViewEngine; razorViewEngine.ViewLocationFormats = razorViewEngine.ViewLocationFormats.Select(x =>
{
return x.Replace("~/Views", string.Format("~/Views/Front/Templates/{0}", template));
}).ToArray();
razorViewEngine.MasterLocationFormats = razorViewEngine.ViewLocationFormats.Select(x =>
{
return x.Replace("~/Views", string.Format("~/Views/Front/Templates/{0}", template));
}).ToArray();
razorViewEngine.PartialViewLocationFormats = razorViewEngine.ViewLocationFormats.Select(x =>
{
return x.Replace("~/Views", string.Format("~/Views/Front/Templates/{0}", template));
}).ToArray();
}

分析
这回导致全局的修改,或者应该增加一个搜索路径(这里就不测试了),因为有些视图是不用多模板支持的,因此这种方式不太适合。
实现思路2
为VIewResult指定路径
public ActionResult Index(string template = "Classic")
{
return this.View("~/Views/Front/Templates/" + template + "/Home/Index.cshtml");
}
分析
这种非常灵活,符合需要,但是代码看起来不够漂亮,好在MVC非常灵活,可以用Filter机制帮我们处理。
实现思路3
Filter机制

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Threading; using Happy.Bootstrap; namespace Happy.Web.Mvc.Template
{
/// <summary>
/// 模板相关。
/// </summary>
public sealed class TemplateRelevantAttribute : ActionFilterAttribute
{
/// <inheritdoc />
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var viewResult = filterContext.Result as ViewResult;
if (viewResult != null)
{
var currentUserTemplate = this.GetCurrentUserTemplate();
var template = string.IsNullOrEmpty(currentUserTemplate) ? TemplateService.DefaultTemplateName : currentUserTemplate;
var controller = filterContext.RequestContext.RouteData.Values["Controller"].ToString();
var action = filterContext.RequestContext.RouteData.Values["Action"].ToString(); if (string.IsNullOrWhiteSpace(viewResult.ViewName))
{
viewResult.ViewName = string.Format(
"~/Views/{0}/{1}/{2}/{3}.{4}",
TemplateService.TemplateDirectoryName,
template,
controller,
action,
TemplateService.TemplateFileExtension); return;
}
} base.OnResultExecuting(filterContext);
} private string GetCurrentUserTemplate()
{
return TemplateService.Current.GetTemplate(Thread.CurrentPrincipal.Identity.Name);
}
}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using Happy.Infrastructure.ExtentionMethods; namespace Happy.Web.Mvc.Template
{
/// <summary>
/// 获取或访问<see cref="ITemplateService"/>实例的唯一入口。
/// </summary>
public static class TemplateService
{
private static readonly EmptyTemplateService _DefaultCommandService = new EmptyTemplateService(); private static TemplateServiceProvider currentProvider = () => _DefaultCommandService; static TemplateService()
{
TemplateDirectoryName = "Templates";
DefaultTemplateName = "Default";
TemplateFileExtension = "cshtml";
} /// <summary>
/// 获取当前应用程序正在使用的模板服务。
/// </summary>
public static ITemplateService Current
{
get { return currentProvider(); }
} /// <summary>
/// 设置当前应用程序正在使用的模板服务提供者。
/// </summary>
public static void SetProvider(TemplateServiceProvider provider)
{
provider.MustNotNull("provider"); currentProvider = provider;
} /// <summary>
/// 模板路径。
/// </summary>
public static string TemplateDirectoryName { get; set; } /// <summary>
/// 默认模板。
/// </summary>
public static string DefaultTemplateName { get; set; } /// <summary>
/// 默认模板。
/// </summary>
public static string TemplateFileExtension { get; set; }
}
}

分析
采用FIlter这种AOP机制,让调用代码看起来非常漂亮,最终就采用这种方式。
测试
代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; using Happy.Web.Mvc.Template; namespace Happy.MvcExample.Controllers
{
[TemplateRelevant]
public class HomeController : Controller
{
//
// GET: /Home/ public ActionResult Index()
{
return View();
} //
// GET: /Home/ public ActionResult ChangeTemplate(string template)
{
TemplateService.DefaultTemplateName = template ?? TemplateService.DefaultTemplateName; return this.RedirectToAction("Index");
}
}
}

运行效果


备注
ViewResult的ViewName可以是绝对路径,也可以是相对路径,默认的相对路径是相对于Controller目录。
ASP.NET MVC:多模板支持的更多相关文章
- Asp.net MVC Razor模板引擎技巧分享
Razor是Asp.net MVC中新的默认模板类型, 语法简单易用.这篇文章不涉及Razor的语法,主要介绍Razor的一些在MVC项目中的使用技巧,以及脱离MVC环境下,如何使用Razor. 阅读 ...
- MVC多模板支持
参考: ASP.NET MVC:多模板支持
- SimpleMembership,成员资格提供程序、 通用的提供者和新的 ASP.NET 4.5 Web 窗体和 ASP.NET MVC 4 模板
ASP.NET MVC 4 互联网模板中添加一些新的. 非常有用的功能,构建 SimpleMembership.这些更改将添加一些很有特色,像很多更简单. 可扩展会员 API 和 OAuth 的支持. ...
- ASP.NET MVC 解析模板生成静态页一(RazorEngine)
简述 Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.在早期的MVC版本中默认使用的是ASPX模板引擎,Razor在语法上的确不错,用起来非常方便,简洁的语法 ...
- ASP.NET MVC]WebAPI应用支持HTTPS的经验总结
WebAPI应用支持HTTPS的经验总结 在我前面介绍的WebAPI文章里面,介绍了WebAPI的架构设计方面的内容,其中提出了现在流行的WebAPI优先的路线,这种也是我们开发多应用(APP.微信. ...
- ASP.NET MVC Bootstrap模板选中菜单高亮显示当前项方法
当我们处理后台显示当前页面,当前页菜单项高亮,我们可以使用js方法,也可用程序实现,使用Bootstrap模板处理高亮并展开方法之一 1.在项目中导入 <script src="/as ...
- ASP.NET MVC使用Bootstrap系统(2)——使用Bootstrap CSS和HTML元素
阅读目录 Bootstrap 栅格(Grid)系统 Bootstrap HTML元素 Bootstrap 验证样式 ASP.NET MVC创建包含Bootstrap样式编辑模板 小结 Bootstra ...
- 转:在ASP.NET MVC中通过URL路由实现对多语言的支持
对于一个需要支持多语言的Web应用,一个很常见的使用方式就是通过请求地址来控制界面呈现所基于的语言文化,比如我们在表示请求地址的URL中将上语言文化代码(比如en或者en-US)来指导服务器应该采用怎 ...
- ASP.NET MVC 5 默认模板的JS和CSS 是怎么加载的?
当创建一个默认的mvc模板后,项目如下: 运行项目后,鼠标右键查看源码,在源码里看到头部和尾部都有js和css文件被引用,他们是怎么被添加进来的呢? 首先我们先看对应的view文件index.csht ...
- ASP.Net MVC 5 in Xamarin Studio 5.2
Xamarin Studio 是一个Mono的跨平台 IDE(Integrated Development Environment),支持Wiindow和Mac,最新发布的5.2 版本支持ASP.NE ...
随机推荐
- UESTC_最少花费 2015 UESTC Training for Dynamic Programming<Problem D>
D - 最少花费 Time Limit: 30000/10000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- 【剑指offer】面试题20:顺时针打印矩阵
题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- poj 1015 Jury Compromise_dp
题意:n个陪审团,每个陪审团有x,y值,选出m个陪审团,要求 (sum(xi)-sum(yi))最少,当 (sum(xi)-sum(yi))最少有多个,取sum(xi)+sum(yi)最大那个 ,并顺 ...
- struts.xml配置文件标签详解
1.package: 作用:分模块化开发. 属性: name:包名. extends:由于struts2框架的一些核心功能的配置都在struts-default包中,所以一般都都直接或间接地继承str ...
- 【Android】使用FrameLayout布局实现霓虹灯效果
FrameLayout是五大布局中最简单的一个布局. 在这个布局中,整个界面被当成一块空白备用区域,所有的子元素都不能被指定放置的位置. 它们统统放于这块区域的左上角,并且后面的子元素直接覆盖在前面的 ...
- Mac神器Iterm2的Shell Integration的用法和注意事项
在iterm2 v3.0版本中有了个新的feature——Shell Integration,其中比较重要的功能就是可以取代传统的“rz”.“sz”(即:向服务器上传.下载文件) 具体的用法可以参见官 ...
- 安装sql server 2008 management studio时,提示升级VS2008 到 SP1
安装sql server 2008 management studio时,提示错误:此计算机上安装了 Microsoft Visual Studio 2008 的早期版本.请在安装 SQL Serve ...
- asp.net 后台对话框,确认跳转
Response.Write("<script>alert('不合法!'); window.location.href='" + ResolveClientUrl(&q ...
- log4.net 日志工具使用
1. 在应用程序的相同目录下建立: winform : 程序名.exe.config .(log4net程序,就log4net.exe.config) web: ...
- java 时间格式化(2016.04.12 12:32:55)
输入的时间格式如:2016.04.12 12:32:55所示: 想要获取一定格式的日期,时间的方法 String startString = "2016.04.25 12:25:44&quo ...