欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

解读ASP.NET 5 & MVC6系列教程(16):自定义View视图文件查找逻辑

程序员文章站 2023-12-14 09:00:34
之前mvc5和之前的版本中,我们要想对view文件的路径进行控制的话,则必须要对iviewengine接口的findpartialview或findview方法进行重写,所...

之前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));
});

上一篇:

下一篇: