之前MVC5和之前的版本中,我们要想对View文件的路径进行控制的话,则必须要对IViewEngine接口的FindPartialViewFindView方法进行重写,所有的视图引擎都继承于该IViewEngine接口,比如默认的RazorViewEngine。但新版本MVC6中,对视图文件的路径方式却不太一样了,目前有两种方式,一种是通过RazorViewEngine,另外一种是通过新特性IViewLocationExpander接口。

通过RazorViewEngine来控制View路径

在新版的RazorViewEngine中,该类提供了两个虚属性(AreaViewLocationFormatsViewLocationFormats),可以用于重写控制,而不必再对FindPartialViewFindView方法进行重写,示例如下:

public class ThemeViewEngine : RazorViewEngine
{
public ThemeViewEngine(IRazorPageFactory pageFactory,
IRazorViewFactory viewFactory,
IViewLocationExpanderProvider viewLocationExpanderProvider,
IViewLocationCache viewLocationCache)
: base(pageFactory,
viewFactory,
viewLocationExpanderProvider,
viewLocationCache)
{
} public override IEnumerable<string> AreaViewLocationFormats
{
get
{
var value = new Random().Next(0, 1);
var theme = value == 0 ? "Theme1" : "Theme2"; // 可通过其它条件,设置皮肤的种类
return base.AreaViewLocationFormats.Select(f => f.Replace("/Views/", "/Views/" + theme + "/"));
}
} public override IEnumerable<string> ViewLocationFormats
{
get
{
var value = new Random().Next(0, 1);
var theme = value == 0 ? "Theme1" : "Theme2"; // 可通过其它条件,设置皮肤的种类
return base.ViewLocationFormats.Select(f => f.Replace("/Views/", "/Views/" + theme + "/"));
}
}
}

然后,通过修改MVcOptions的实例属性ViewEngines即可完成对视图引擎的替换,代码如下:

services.AddMvc().Configure<MvcOptions>(options =>
{
options.ViewEngines.Clear();
options.ViewEngines.Add(typeof(ThemeViewEngine));
});

这样,系统在查找视图文件的时候,就会按照新注册的ThemeViewEngine的逻辑来执行。

通过IViewLocationExpander来控制View路径

在MVC6中,微软还提供了另外一种新的方式来控制View文件的路径,那就是IViewLocationExpander接口,通过实现该接口即可实现自定义逻辑,并且也可以使用相关的上下文对象。示例如下:

public class ThemeViewLocationExpander : IViewLocationExpander
{
public void PopulateValues(ViewLocationExpanderContext context)
{
var value = new Random().Next(0, 1);
var theme = value == 0 ? "Theme1" : "Theme2";
context.Values["theme"] = theme;
} public virtual IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
IEnumerable<string> viewLocations)
{
return viewLocations.Select(f => f.Replace("/Views/", "/Views/" + context.Values["theme"] + "/"));
}
}

在上述自定义的IViewLocationExpander中,实现了2个方法分别是PopulateValuesExpandViewLocationsPopulateValues方法可以让我们想ViewLocationExpanderContext上下文中添加响应的键值对以便后续使用,通过,我们可以利用通过该上下文对象,来查找ActionContextHttpContext对象,以便利用这些对象做响应的判断操作;而ExpandViewLocations方法,只会在没有View缓存或在View缓存里找不到对应key的View文件时才会调用该方法,在该方法内,我们可以动态返回视图的位置。

最后,我们在Startup.cs里通过修改RazorViewEngineOptions实例对象的ViewLocationExpanders属性,来实现注册目的,代码如下:

services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(typeof(ThemViewLocationExpander));
});

同步与推荐

本文已同步至目录索引:解读ASP.NET 5 & MVC6系列

解读ASP.NET 5 & MVC6系列(16):自定义View视图文件查找逻辑的更多相关文章

  1. 解读ASP.NET 5 & MVC6系列

    本系列的大部分内容来自于微软源码的阅读和网络,大部分测试代码都是基于VS RC版本进行测试的. 解读ASP.NET 5 & MVC6系列(1):ASP.NET 5简介 解读ASP.NET 5 ...

  2. 解读ASP.NET 5 & MVC6 ---- 系列文章

    本系列的大部分内容来自于微软源码的阅读和网络,大部分测试代码都是基于VS RC版本进行测试的. 解读ASP.NET 5 & MVC6系列(1):ASP.NET 5简介 解读ASP.NET 5 ...

  3. 解读ASP.NET 5 & MVC6系列(15):MvcOptions配置

    程序模型处理 IApplicationModelConvention 在MvcOptions的实例对象上,有一个ApplicationModelConventions属性(类型是:List<IA ...

  4. 解读ASP.NET 5 & MVC6系列(14):View Component

    在之前的MVC中,我们经常需要类似一种小部件的功能,通常我们都是使用Partial View来实现,因为MVC中没有类似Web Forms中的WebControl的功能.但在MVC6中,这一功能得到了 ...

  5. 解读ASP.NET 5 & MVC6系列(13):TagHelper

    在新版的MVC6中,微软提供了强大的TagHelper功能,以便让我们摆脱如下的臃肿代码: @Html.LabelFor(model => model.FullName) @Html.EditF ...

  6. 解读ASP.NET 5 & MVC6系列(12):基于Lamda表达式的强类型Routing实现

    前面的深入理解Routing章节,我们讲到了在MVC中,除了使用默认的ASP.NET 5的路由注册方式,还可以使用基于Attribute的特性(Route和HttpXXX系列方法)来定义.本章,我们将 ...

  7. 解读ASP.NET 5 & MVC6系列(11):Routing路由

    新版Routing功能介绍 在ASP.NET 5和MVC6中,Routing功能被全部重写了,虽然用法有些类似,但和之前的Routing原理完全不太一样了,该Routing框架不仅可以支持MVC和We ...

  8. 解读ASP.NET 5 & MVC6系列(10):Controller与Action

    我们知道在MVC5和之前的版本,两个框架的生命周期是不一样的,在新版MVC6中,MVC Controller/Web API Controller已经合二为一了,本章我们主要讲解Controller和 ...

  9. 解读ASP.NET 5 & MVC6系列(8):Session与Caching

    在之前的版本中,Session存在于System.Web中,新版ASP.NET 5中由于不在依赖于System.Web.dll库了,所以相应的,Session也就成了ASP.NET 5中一个可配置的模 ...

随机推荐

  1. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 特殊问题和实战经验(五)

    RAC 特殊问题和实战经验(五) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  2. 6.JAVA之GUI编程Action事件

    功能:单击一个按钮实现关闭窗口: import java.awt.*; import java.awt.event.*; public class StudyAction { // 定义该图形所需的组 ...

  3. passport源码研究

            passport的验证过程主要依赖具体的验证策略来实现的,比较常用的有session策略.local策略和github策略等,验证逻辑都是在这些策略类中定义的.passport模块的定 ...

  4. 翻译:使用 ASP.NET MVC 4, EF, Knockoutjs and Bootstrap 设计和开发站点 - 6 - 业务逻辑

    Part 3: 设计逻辑层:核心开发 如前所述,我们的解决方案如下所示: 下面我们讨论整个应用的结构,根据应用中不同组件的逻辑相关性,分离到不同的层中,层与层之间的通讯通过或者不通过限制.分层属于架构 ...

  5. C#开发微信门户及应用(25)-微信企业号的客户端管理功能

    我们知道,微信公众号和企业号都提供了一个官方的Web后台,方便我们对微信账号的配置,以及相关数据的管理功能,对于微信企业号来说,有通讯录中的组织架构管理.标签管理.人员管理.以及消息的发送等功能,其中 ...

  6. JDK1.8 HashMap 源码分析

    一.概述 以键值对的形式存储,是基于Map接口的实现,可以接收null的键值,不保证有序(比如插入顺序),存储着Entry(hash, key, value, next)对象. 二.示例 public ...

  7. POI读取EXCEL(2007以上)

    import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; im ...

  8. 微信小程序注册

    小程序是一种新的开放能力,可以在微信内被便捷地获取和传播,同时具有出色的使用体验.开发者可以根据平台提供的能力,快速地开发一个小程序. 开放内容包括: 1.开放注册范围:企业.政府.媒体.其他组织: ...

  9. 使用PowerShell修改操作系统“环境变量”

      有时候我们需要命令行工具,但在使用前往往需要先导航至命令工具所在的目录,比如:stsadm 我们首先需要导航至(以SharePoint2013为例):C:\Program Files\Common ...

  10. Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead的解决办法

    今天在导入工程进Eclipse的时候竟然出错了,控制台输出的是: [2013-02-04 22:17:13 - takepicture] Android requires compiler compl ...