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 ...
随机推荐
- 使用PHP从web访问mysql数据库
一. web数据库构架的工作原理 1. 用户由浏览器发出HTTP请求,请求特定的web页面. 2. web服务器接受接收到对特定页面的请求,检索相应文件,并将其传递给php引擎处理. 3. php引擎 ...
- 新发现一个函数:GradientFill
位于Msimg32.dll之中 https://msdn.microsoft.com/en-us/library/windows/desktop/dd144957(v=vs.85).aspx
- 【Xamarin挖墙脚系列:常用的Mac 命令】
通俗点说Mac 跟Linux的爹都是Unix,他们都加入了标准的Shell命令工具,bash 所以俩系统中的命令基本通用 Linux下的操作手册,本人自己整理了一份.呵呵~~~~ 还可以使用客户端远程 ...
- java设计模式--创建模式--工厂方法
工厂方法定义: 工厂方法 概述 定义一个用于创建对象的接口,让子类决定实例化哪一个类.FactoryMethod使一个类的实例化延迟到其子类. 适用性 .当一个类不知道它所必须创建的对象的类的时候. ...
- 安装 Kali Linux 后需要做的 20 件事
安装 Kali Linux 后需要做的 20 件事 本文含有我觉得有用的每一件事情.本文分为三大部分: 专门针对Kali用户 Kali Linux是来自Debian的一个特殊版本,Kali Linux ...
- Entity Framework 技术参考:http://kb.cnblogs.com/zt/ef/
Entity Framework 技术参考:http://kb.cnblogs.com/zt/ef/
- unmount的时候报错
卸载存储的时候报错 device is busy 解决办法 例:/mnt/test 为存储挂载点 fuser -m -v /mnt/test fuser 可以显示出当前哪个程序在使用磁盘上的某个文件. ...
- PHP MySQL Where 子句 之Where
WHERE 子句 如需选取匹配指定条件的数据,请向 SELECT 语句添加 WHERE 子句. 语法 SELECT column FROM table WHERE column operator va ...
- 使用Memcache在PHP中调试方法的介绍及应用
使用Memcache在PHP中调试方法的介绍及应用 如果我们在网络开发中,特别是大访问量的web项目开发中,为了提高响应速度,减少数据查询运算,那么我们都会选用memcahce.首先我们必须要安装,接 ...
- 很少人知道的office专用卸载工具
Microsoft Office是微软公司开发的一套基于 Windows 操作系统的办公软件套装.常用组件有 Word.Excel.Powerpoint等.当我们不需要再用了或者想安装旧版本的话,首先 ...