MVC (Model View Controller) allows you to create different screen components to help development of your site. Here is a short introduction that helps you to understand some practices of building good application.
Shared MVC views
MVC contains three shared views:
- _Layout.cshtml (in /Views/Shared)
File defines common layout for “all” views. You can create custom layout file if required, but I don’t recommend doing it. It’s seldom needed. You should keep it as the last resort. Layout file defines body section (not same as HTML body tag) and one or more sections. Default layout file contains one scripts section that allows developer to inject script tags from view to rendered page.
- _ViewImports.cshtml (in /Views)
File defines import statements (same as using statements in C# code). This is hierarchical. Each folder can contain one. You should carefully think what you want to put here. I recommend that you add to common _ViewImports.cshtml file in /Views folder only those namespaces you really require in “every” page and if you will create controller level files, you will put only common definitions shared in all views to that file.
- _ViewStart.cshtml (in /Views)
File defines code executed before view. This file is also hierarchical. Each folder can contain one. If folder contains _ViewStart.chtml file, it will be executed after shared one. Default file defines Layout file that view uses. I personally wouldn’t use this for any custom code. You can Controller or Service to provide additional logic you need in your page or use some other technique to add logic in place you can better manage (create unit tests etc.).
You should always remember that if something is technically possible, it’s not always the recommended way of doing things like over using those three files.
As described above layout is used for creating common layout for all views. There are couple things you should know about placement of different html elements in the file.
View imports is used mainly for declaring namespaces for view. It also contains several other purposes. As I have already said, you shouldn’t use all possible features even they are technically possible. This applies to imports file well. If multiple _ViewImports.cshtml files are run for a view, combined behavior of the directives included in the ViewImports.cshtml files will be as follows:
- @addTagHelper, @removeTagHelper: all run, in order
I recommend that you define all used tag helpers to main imports file in Views folder. Tag helpers should be common for your application. If you will end up having view specific tag helpers, you should consider if you are developing maintenance nightmare or are your tag helpers doing too much inside one tag helper.
- @tagHelperPrefix: the closest one to the view overrides any others
I don’t recommend using this at all. Your tag helpers should follow HTML syntax and there are no namespaces or prefixes.
- @model: the closest one to the view overrides any others
If you want to define model to here, you really should be sure that you can reuse same model in all or almost all views this imports file is affecting. In any other case, you shouldn’t use this setting either. Preferred way is to define model in view.
- @inherits: the closest one to the view overrides any others
This will allow you to create a custom page class instead of default RazorPage<T> where T is the model you defined for the page. This can be useful in some special cases where you want to all some custom functionality to page. In most cases however this can be done with several other means like tag helpers or dependency injection. I personally find this a method echo from the old days.
- @using: all are included; duplicates are ignored
This is the most common usage for the imports file. It helps you to import common namespaces to your views. In most cases you will have own namespaces for view models that are specific to one domain. You can easily add those namespaces to all your domain specific views by creating own imports file to same folder where your views are.
- @inject: for each property, the closest one to the view overrides any others with the same property name
Inject allows you to add additional services to the views. I think the most common use case is to add Localizer to your views if you want to use multilingual site. You should use inject in same way as tag helpers. Add inject lines to common imports file and do not use inject directive in any other imports file unless you have really good reason for it.
View start allows you to execute common code in views. This can be used similar cases as inherits directive could be used. Code is executed in all views that are in same folder or any sub folders beneath view start file. This means that you need to be sure that all views can execute this code. I recommend that you will use some other method to achieve similar functionality.
Building ASP.Net MVC site series: