Interpretation of ASP. NET 5 MVC 6 Series Tutorials (16): Customizing View View File Lookup Logic

  • 2021-07-26 07:27:42
  • OfStack

In previous MVC 5 and previous versions, if we want to control the path of View files, we must control the IViewEngine Interface's FindPartialView Or FindView Method, all view engines inherit from the IViewEngine Interface, such as the default RazorViewEngine . However, in the new version of MVC6, the path mode of view file is not very 1. At present, there are two ways, one is through RazorViewEngine The other one is through new features IViewLocationExpander Interface.

Control the View path through RazorViewEngine

In the new edition of RazorViewEngine The class provides two virtual attributes ( AreaViewLocationFormats And ViewLocationFormats ), can be used to override control without having to FindPartialView Or FindView Method, as shown below:


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"; //  The type of skin can be set by other conditions 
      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"; //  The type of skin can be set by other conditions 
      return base.ViewLocationFormats.Select(f => f.Replace("/Views/", "/Views/" + theme + "/"));
    }
  }
}

Then, the replacement of the view engine can be completed by modifying the instance property ViewEngines of MVcOptions. The code is as follows:


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

In this way, when the system looks for the view file, it will follow the newly registered ThemeViewEngine To execute the logic of.

Control the View path through IViewLocationExpander

In MVC 6, Microsoft also provides another new way to control the path of View files, which is IViewLocationExpander Interface, which you can implement to implement custom logic, and you can also use related context objects. Examples are as follows:


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"] + "/"));
  }
}

In the above customized IViewLocationExpander Two methods are implemented, which are PopulateValues And ExpandViewLocations , PopulateValues The method can make us think ViewLocationExpanderContext Add the key-value pair of the response to the context for later use. By, we can use the context object to find ActionContext And HttpContext Objects, so that these objects can be used to judge the response; And ExpandViewLocations Method, which is called only when there is no View cache or the View file corresponding to key cannot be found in the View cache, in which we can dynamically return the location of the view.

Finally, we are in Startup.cs By modifying RazorViewEngineOptions Object of the instance object ViewLocationExpanders Property to achieve the registration purpose, the code is as follows:


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

Related articles: