- Modern Web Development with ASP.NET Core 3
- Ricardo Peres
- 615字
- 2021-06-18 18:36:03
Locating views
When asked to return a view (ViewResult), the framework needs first to locate the view file (.cshtml).
The built-in conventions around locating view files are as follows:
- View files end with the cshtml extension.
- View filenames should be identical to the view names, minus the extension (for example, a view of Index will be stored in a file named Index.cshtml).
- View files are stored in a Views folder and inside a folder named after the controller they are returned from—for example, Views\Home.
- Global or shared views are stored in either the Views folder directly or inside a Shared folder inside of it—for example, Views\Shared.
Actually, this is controlled by the ViewLocationFormats collection of the RazorViewEngineOptions class (Razor is the only included view engine). This has the following entries, by default:
- /Views/{1}/{0}.cshtml
- /Views/Shared/{0}.cshtml
If you want the Razor engine to look in different locations, all you need to do is tell it; so, through the AddRazorOptions method, that is usually called in sequence to AddMvc, in the ConfigureServices method, like this:
services
.AddMvc()
.AddRazorOptions(options =>
{
options.ViewLocationFormats.Add("/AdditionalViews/{0}.cshtml");
});
The view locations are searched sequentially in the ViewLocationFormats collection until one file is found.
The actual view file contents are loaded through IFileProviders. By default, only one file provider is registered (PhysicalFileProvider), but more can be added through the configuration. The code can be seen in the following snippet:
services
.AddMvc()
.AddRazorOptions(options =>
{
options.FileProviders.Add(new CustomFileProvider());
});
Adding custom file providers may prove useful—for example, if you want to load contents from non-orthodox locations, such as databases, ZIP files, assembly resources, and so on. There are multiple ways to do this. Let's try them in the following subsections.
Using view location expanders
There is an advanced feature by which we can control, per request, the locations to search the view files: it's called view location expanders. View location expanders are a Razor thing, and thus are also configured through AddRazorOptions, as illustrated in the following code snippet:
services
.AddMvc()
.AddRazorOptions(options =>
{
options.ViewLocationExpanders.Add(new ThemesViewLocationExpander
("Mastering"));
});
A view location expander is just some class that implements the IViewExpander contract. For example, imagine you want to have a theme framework that would add a couple of folders to the views search path. You could write it like this:
public class ThemesViewLocationExpander : IViewLocationExpander
{
public ThemesViewLocationExpander(string theme)
{
this.Theme = theme;
}
public string Theme { get; }
public IEnumerable<string> ExpandViewLocations(
ViewLocationExpanderContext context,
IEnumerable<string> viewLocations)
{
var theme = context.Values["theme"];
return viewLocations
.Select(x => x.Replace("/Views/", "/Views/" + theme + "/"))
.Concat(viewLocations);
}
public void PopulateValues(ViewLocationExpanderContext context)
{
context.Values["theme"] = this.Theme;
}
}
The default search locations, as we've seen, are the following:
- /Views/{1}/{0}.cshtml
- /Views/Shared/{0}.cshtml
By adding this view location expander, for a theme called Mastering, these will become the following:
- /Views/{1}/{0}.cshtml
- /Views/Mastering/{1}/{0}.cshtml
- /Views/Shared/Mastering/{0}.cshtml
- /Views/Shared/{0}.cshtml
The IViewLocationExpander interface defines only two methods, as follows:
- PopulateValues: Used to initialize the view location expander; in this example, I used it to pass some value in the context.
- ExpandViewLocations: This will be called to retrieve the desired view locations.
View location expanders are queued, so they will be called in sequence, from the registration order; each ExpandViewLocations method will be called with all the locations returned from the previous one.
Both methods, through the context parameter, have access to all the request parameters (HttpContext, RouteData, and so on), so you can be as creative as you like, and define the search locations for the views according to whatever rationale you can think of.
- Facebook Application Development with Graph API Cookbook
- 案例式C語言程序設計
- Mastering Adobe Captivate 2017(Fourth Edition)
- 零基礎學Scratch少兒編程:小學課本中的Scratch創意編程
- Mastering phpMyAdmin 3.4 for Effective MySQL Management
- Python零基礎快樂學習之旅(K12實戰訓練)
- INSTANT Mercurial SCM Essentials How-to
- 3D少兒游戲編程(原書第2版)
- SAP BusinessObjects Dashboards 4.1 Cookbook
- Symfony2 Essentials
- 深入淺出React和Redux
- C++程序設計教程(第2版)
- Node.js區塊鏈開發
- WildFly Cookbook
- Python編程入門(第3版)