定制属于你自己的ViewEngine(一套逻辑多套UI)
ASP.NET MVC出来这么久了,心中却又很多的疑惑:为什么所有的View都要放在Views目录下? 为什么Shared文件夹下面的页面可以被共享? 为什么Page既可以是*.cshtml,也可以是*.aspx?
其实上面的几个问题归结起来都是视图引擎的功效。
在传统的ASP.NET中,可能还没有ViewEngine的概念。因为在Web From里面,实现Page实现了IHttpHanlder的接口,所以Page既是响应的处理类,也是视图的渲染类。在ASP.NET MVC中,视图的概念被抽象了出来,试图引擎的概念也被抽象成了一个接口。
首先来看一下IViewEngine接口的定义
namespace System.Web.Mvc
{
public interface IViewEngine
{
ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
void ReleaseView(ControllerContext controllerContext, IView view);
}
}
总共3个函数,总结起来大概就是两个功能:Find & Release。
默认情况下,ASP.NET MVC提供了两个视图引擎:WebFormViewEngine和RazorViewEngine
namespace System.Web.Mvc
{
public static class ViewEngines
{
private static readonly ViewEngineCollection _engines = new ViewEngineCollection
{
new WebFormViewEngine(),
new RazorViewEngine(),
}; public static ViewEngineCollection Engines
{
get { return _engines; }
}
}
}
这就是为什么ASP.NET MVC既支持*.aspx,又支持*.cshtml的原因了(个人觉得如果已经确定要使用RazorView的话,不如把WebFormViewEngine给移除,可能对性能会有所帮助)。
那为什么所有的视图都要放在Views目录下呢,这个就要拜RazorViewngines所赐了。
下面是RazorViewEngine的构造函数:
public RazorViewEngine(IViewPageActivator viewPageActivator)
: base(viewPageActivator)
{
AreaViewLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
AreaMasterLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
AreaPartialViewLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
}; ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
MasterLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
PartialViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
}; FileExtensions = new[]
{
"cshtml",
"vbhtml",
};
}
所有的寻址路径都被格式化了,是不是很眼熟呢,关于这里为啥用数组而不用List,个人觉得,数组的寻址效率要更高些,遍历速度更快。
好了,找了“罪魁祸首”,就好好地调教一个,让它乖乖听话,小样让去哪就去哪里。
/// <summary>
/// razor视图引擎扩展
/// </summary>
public class CustomerViewEngine : RazorViewEngine
{
/// <summary>
/// 可以分开部署不同语种
/// </summary>
/// <param name="engineName"></param>
public CustomerViewEngine(string engineName)
{
base.ViewLocationFormats = new[]
{
"~/Views" + engineName + "/{1}/{0}.cshtml",
"~/Views" + engineName + "/Shared/{0}.cshtml"
}; base.PartialViewLocationFormats = new[]
{
"~/Views" + engineName + "/{1}/{0}.cshtml",
"~/Views" + engineName + "/Shared/{0}.cshtml"
}; base.AreaViewLocationFormats = new[]
{
"~Areas/{2}/Views" + engineName + "/{1}/{0}.cshtml",
"~Areas/{2}/Views" + engineName + "/Shared/{0}.cshtml"
}; base.AreaPartialViewLocationFormats = new[]
{
"~Areas/{2}/Views" + engineName + "/{1}/{0}.cshtml",
"~Areas/{2}/Views" + engineName + "/Shared/{0}.cshtml"
};
} public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
this.SetEngine(controllerContext);
return base.FindView(controllerContext, viewName, masterName, useCache);
} public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
this.SetEngine(controllerContext);
return base.FindPartialView(controllerContext, partialViewName, useCache);
} /// <summary>
/// 根据条件自行设置,目前是chrome浏览器就展示默认的
/// 不是chrome浏览器的话就展示/Themes/Eleven下的
/// 可以直接测试是移动端还是pc端
/// 然后写入cookie
/// </summary>
private void SetEngine(ControllerContext controllerContext)
{
string engineName = "/Themes/Eleven";
if (controllerContext.HttpContext.Request.UserAgent.IndexOf("Chrome/65") >= )
{
engineName = null;
} //if (controllerContext.HttpContext.Request.IsMobile())//检测是不是移动端
//{
// engineName = null;
//} base.ViewLocationFormats = new[]
{
"~/Views" + engineName + "/{1}/{0}.cshtml",
"~/Views" + engineName + "/Shared/{0}.cshtml"
}; base.PartialViewLocationFormats = new[]
{
"~/Views" + engineName + "/{1}/{0}.cshtml",
"~/Views" + engineName + "/Shared/{0}.cshtml"
}; base.AreaViewLocationFormats = new[]
{
"~Areas/{2}/Views" + engineName + "/{1}/{0}.cshtml",
"~Areas/{2}/Views" + engineName + "/Shared/{0}.cshtml"
}; base.AreaPartialViewLocationFormats = new[]
{
"~Areas/{2}/Views" + engineName + "/{1}/{0}.cshtml",
"~Areas/{2}/Views" + engineName + "/Shared/{0}.cshtml"
};
}
接下去就很简单了,只需要把原来的视图引擎清空,加载自己的视图引擎就可以了
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new CustomViewEngine()); RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
定制属于你自己的ViewEngine(一套逻辑多套UI)的更多相关文章
- 10套免费的 Photoshop UI 元素以及 PSD 素材
免费的 PSD 用户界面工具包以及可以编辑 Photoshop PSD 文件,有你需要的设计漂亮的用户界面和惊人使用体验.这些用户界面工具包可有免费下载,可随意定制的,而且这些 PSD 分层素材文件组 ...
- 分享一套精美的现代 UI PSD 工具包【免费下载】
艾库特·耶尔马兹,是土耳其伊斯坦布尔的一位高级艺术总监,他向大家分享了一套美丽的现代 UI 工具包,你可以免费下载.所以,你可以使用这个优秀的素材设计视觉互动和有吸引力的用户界面. 此 UI 套件提供 ...
- 免费素材:25套免费的 Web UI 设计的界面元素(转)
Web 元素是任何网站相关项目都需要的,质量和良好设计的元素对于设计师来说就像宝贝一样.如果您正在为您的网站,博客,Web 应用程序或移动应用程序寻找完美设计的网页元素,那么下面这个列表会是你需要的. ...
- socket , 套接口还是套接字,傻傻分不清楚
socket 做网络通信的朋友大都对socket这个词不会感到陌生,但是它的中文翻译是叫套接口还是套接字呢,未必大多数朋友能够分清,今天我们就来聊聊socket的中文名称. socket一词的起源 在 ...
- ASP.NET MVC - 定制属于你自己的ViewEngine
http://blog.csdn.net/jackvs/article/details/7788743 ASP.NET MVC出来这么久了,心中却又很多的疑惑:为什么所有的View都要放在Views目 ...
- React 同构
React 同构 搬运 https://segmentfault.com/a/1190000004671209 究竟什么是同构呢? 同构就是希望前端 后端都使用同一套逻辑 同一套代码 Nodejs出现 ...
- mvc架构和mvp架构
mvc,mvp其实是复合模式,是多个设计模式的组合:将多个模式结合起来形成一个框架,已解决一般性问题. mvc: 既然mvc是复合模式,那么是由哪些设计模式组合的呢? 观察者设计模式:view和con ...
- 网购的一套UI代码的始末
引言: 一个商业项目的需要,又因为时间紧迫的关系,准备购买一套简洁,易用,可定制化强的UI,经过对国内外多家UI产品进行了对比, 包括:FineUI, EasyUI, EXT.NET, EXTJS, ...
- Java快速开发平台,JEECG 3.7.7闪电版本发布,增加多套主流UI代码生成器模板
JEECG 3.7.7 闪电版本发布,提供5套主流UI代码生成器模板 导读 ⊙平台性能优化,速度闪电般提升 ⊙提供5套新的主流UI代码生成器模板(Bootstrap表单+Boots ...
随机推荐
- zabbix 内存溢出
tail -f /var/log/zabbix/zabbix_server_log ::165110.914 ================================ ::165110.914 ...
- SpringBootMVC04——Mybatis
简介 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动.创建connection.创建statement. ...
- System.Windows.Forms.Application.DoEvents();
关于Application.DoEvents()的小研究 在MSDN中的备注是: 当运行 Windows 窗体时,它将创建新窗体,然后该窗体等待处理事件.该窗体在每次处理事件时,均将处理与该事件关联的 ...
- 七、设备驱动中的阻塞与非阻塞 IO(一)
7.1 阻塞与非阻塞 IO 阻塞操作是指在执行设备操作的时候,若不能获取资源,则挂起进程直到满足可操作的条件后再进行操作.被挂起的进程进入睡眠状态,被从调度器的运行队列移走,直到等待的条件被满足. 非 ...
- 第三篇:解析库之re、beautifulsoup、pyquery
BeatifulSoup模块 一.介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Be ...
- ESP8266-Soft AP模式 —— 谁想连上我
AP是Access Point简称,也就是访问接入点,是网络的中心节点.一般家庭的无线路由器就是一个AP,众多站点(STA)加入到它所组成的无线网络,网络中的所有的通信都通过AP来转发完成. 软AP也 ...
- python 操作符**与*的用法
- vue 搜索关键词 变颜色
<a class="text"> <span>{{item.name.slice(0,item.name.toLowerCase().indexOf(inp ...
- webUploader---实现大文件断点续传
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- TTTTTTTTTTTTTT CDOJ Sliding Window 线段树(nlogn)或双端队列(n) 模板
题目链接: L - Sliding Window Time Limit:6000MS Memory Limit:131072KB 64bit IO Format:%lld & ...