之前mvc5和之前的版本中,我们要想对view文件的路径进行控制的话,则必须要对iviewengine接口的findpartialview或findview方法进行重写,所有的视图引擎都继承于该iviewengine接口,比如默认的razorviewengine。但新版本mvc6中,对视图文件的路径方式却不太一样了,目前有两种方式,一种是通过razorviewengine,另外一种是通过新特性iviewlocationexpander接口。
通过razorviewengine来控制view路径
在新版的razorviewengine中,该类提供了两个虚属性(areaviewlocationformats和viewlocationformats),可以用于重写控制,而不必再对findpartialview或findview方法进行重写,示例如下:
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个方法分别是populatevalues和expandviewlocations,populatevalues方法可以让我们想viewlocationexpandercontext上下文中添加响应的键值对以便后续使用,通过,我们可以利用通过该上下文对象,来查找actioncontext和httpcontext对象,以便利用这些对象做响应的判断操作;而expandviewlocations方法,只会在没有view缓存或在view缓存里找不到对应key的view文件时才会调用该方法,在该方法内,我们可以动态返回视图的位置。
最后,我们在startup.cs里通过修改razorviewengineoptions实例对象的viewlocationexpanders属性,来实现注册目的,代码如下:
services.configure<razorviewengineoptions>(options =>
{
options.viewlocationexpanders.add(typeof(themviewlocationexpander));
});
发表评论