• MVC修改视图的默认路径


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

    MVC5和之前的版本:

     1   public class ViewEngine : RazorViewEngine
     2     {
     3          /// <summary>
     4         /// Initializes a new instance of the <see cref="ViewEngine"/> class.
     5         /// </summary>
     6         public ViewEngine()
     7          {
     8             var views = new[]
     9             {
    10                 "~/Views/{1}/{0}.cshtml",
    11                 "~/Views/Shared/{0}.cshtml",
    12                 "~/Views/Base/{0}.cshtml",
    13                 "~/Views/Base/{1}/{0}.cshtml",
    14             };
    15 
    16             this.PartialViewLocationFormats = views;
    17 
    18             this.ViewLocationFormats = views;
    19         }
    20 
    21         /// <summary>
    22         /// 添加视图规则
    23         /// </summary>
    24         /// <param name="viewEngineCollection">viewEngineCollection</param>
    25         internal static void RegisterView(ViewEngineCollection viewEngineCollection)
    26         {
    27             viewEngineCollection.Add(new ViewEngine());
    28         }

    在Application_Start()中添加语句:

    // 注册视图规则
    ViewEngine.RegisterView(ViewEngines.Engines);

    MVC6:

    通过RazorViewEngine来控制View路径

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

     1 public class ThemeViewEngine : RazorViewEngine
     2 {
     3     public ThemeViewEngine(IRazorPageFactory pageFactory,
     4         IRazorViewFactory viewFactory,
     5         IViewLocationExpanderProvider viewLocationExpanderProvider,
     6         IViewLocationCache viewLocationCache)
     7         : base(pageFactory,
     8                 viewFactory,
     9                 viewLocationExpanderProvider,
    10                 viewLocationCache)
    11     {
    12     }
    13 
    14     public override IEnumerable<string> AreaViewLocationFormats
    15     {
    16         get
    17         {
    18             var value = new Random().Next(0, 1);
    19             var theme = value == 0 ? "Theme1" : "Theme2";  // 可通过其它条件,设置皮肤的种类
    20             return base.AreaViewLocationFormats.Select(f => f.Replace("/Views/", "/Views/" + theme + "/"));
    21         }
    22     }
    23 
    24     public override IEnumerable<string> ViewLocationFormats
    25     {
    26         get
    27         {
    28             var value = new Random().Next(0, 1);
    29             var theme = value == 0 ? "Theme1" : "Theme2";  // 可通过其它条件,设置皮肤的种类
    30             return base.ViewLocationFormats.Select(f => f.Replace("/Views/", "/Views/" + theme + "/"));
    31         }
    32     }
    33 }

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

    1 services.AddMvc().Configure<MvcOptions>(options =>
    2 {
    3     options.ViewEngines.Clear();
    4     options.ViewEngines.Add(typeof(ThemeViewEngine));
    5 });

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

    通过IViewLocationExpander来控制View路径

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

     1 public class ThemeViewLocationExpander : IViewLocationExpander
     2 {
     3     public void PopulateValues(ViewLocationExpanderContext context)
     4     {
     5         var value = new Random().Next(0, 1);
     6         var theme = value == 0 ? "Theme1" : "Theme2";
     7         context.Values["theme"] = theme;
     8     }
     9 
    10     public virtual IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
    11                                                             IEnumerable<string> viewLocations)
    12     {
    13         return viewLocations.Select(f => f.Replace("/Views/", "/Views/" + context.Values["theme"] + "/"));
    14     }
    15 }

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

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

    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.ViewLocationExpanders.Add(typeof(ThemViewLocationExpander));
    });
  • 相关阅读:
    day22 sys模块(☆☆☆)json & pickle模块(☆☆☆☆)
    day22 OS模块
    day21 time时间模块
    day21 if __name__==""__main__""的用法
    day21 模块
    day20 装饰器 (装饰器=高阶函数+函数嵌套+闭包)加上参数
    day19 生产者模型-next与send用法详解-生产者消费者模型
    day19 生成器函数的好处
    zzq's sort [思维题]
    三元组 [01Trie]
  • 原文地址:https://www.cnblogs.com/liuxiaoji/p/4571995.html
Copyright © 2020-2023  润新知