Saeve
October 3, 2025, 11:11am
1
This is a continuation of the talk about how Views work from the discussion in:
Yeah, if they’re not in the publish directory then you shouldn’t see views deployed. In an Umbraco project it’s normal to have have CopyRazorGenerateFilesToPublishDirectory enabled in the csproj - presumably you don’t?
The observation about compiled razor views is just that if you have views in that directory they will override any that you have precompiled in DLLs and .NET will still watch the views directory for changes - this is because Umbraco includes the runtime compilation package for R…
It’s been moved to it’s own topic since it technically isn’t related to the original topic.
Hopefully we can all learn at bit more about how templates work in production on Umbraco 16.
Saeve
October 3, 2025, 11:12am
2
I hope tagging you, @JasonElkin , here is okay, so we can continue our talk here
1 Like
JasonElkin
(Jason Elkin)
October 3, 2025, 1:33pm
3
Basically runtime compilation is always on. Umbraco has a dependency on Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation and so long as that DLL is loaded, runtime compilation is turned on.
Apart from being able to modify views in production, there are also some performance considerations. There are filewatchers on views, and requests will check that views are not newer than compiled resources before serving a view (i.e. every request = call to disk instead of just memory). Actually, this is what alerted us to the situation, we were profiling a high traffic site and trying to work out where the extra calls to disk where coming from.
RuntimeCompilation is being deprecated in .NET 10 though , and HQ are going to get to work removing it - probably not in time for v17.
A few other relevant bits of info:
v10/dev ← v10/feature/runtime-mode
opened 02:52PM - 28 Jun 22 UTC
### Prerequisites
- [x] I have added steps to test this contribution in the d… escription below
This is a v10 implementation of PR https://github.com/umbraco/Umbraco-CMS/pull/12203 (that I've now closed, as we won't introduce this to v9 anymore).
### Description
The default settings of Umbraco are primarily configured for a great developer experience (which is a very good thing), but that means you need to make sure you update these settings correctly when publishing your site to production to ensure it's running optimally.
Some of these development features are also always enabled (like Razor runtime compilation and support for in-memory ModelsBuilder generation using a custom `RefreshingRazorViewEngine`), but have a negative effect on performance and/or stability of your site. You also need to use a different development workflow to be able to disable these features on production, making it not so obvious and easy to do (hence it's quite often not done at all).
This PR therefore introduces a runtime mode setting (`Umbraco:CMS:Runtime:Mode`) that can be set to the following:
- `BackofficeDevelopment` (default) - leave everything enabled to allow for rapid development (including doing all development from within the backoffice);
- `Development` - disable in-memory ModelsBuilder generation and require them to be generated using `SourceCodeAuto`/`SourceCodeManual` (which requires manually recompiling the project after the models have changed, e.g. after updating document or data types) - this ensures the models will also be available on the production environment;
- `Production` - also disable Razor (cshtml) runtime compilation, requiring you to compile your views at build/publish time (by removing the `RazorCompileOnBuild` and `RazorCompileOnPublish` ~and `CopyRazorGenerateFilesToPublishDirectory`~ properties from your project file) and enforce specific settings for optimal performance/security.
Validation of these settings are done when determining the runtime level during startup using the new `IRuntimeModeValidationService` and when it fails, causes a `BootFailedException` to be thrown. The default implementation gets all registered `IRuntimeModeValidator`s to do the validation, making it possible to remove default checks and/or add your own (inherit from `RuntimeModeProductionValidatorBase` if you only want to validate against the production runtime mode). The following validators are added by default:
- `JITOptimizerValidator` - Ensure the application is built/published in Release mode (with JIT optimization enabled) when in production runtime mode, e.g. using `dotnet publish --configuration Release`;
- `UmbracoApplicationUrlValidator` - ensure `Umbraco:CMS:WebRouting:UmbracoApplicationUrl` is configured when in production runtime mode;
- `UseHttpsValidator` - ensure `Umbraco:CMS:Global:UseHttps` is enabled when in production runtime mode;
- `RuntimeMinificationValidator` - ensure `Umbraco:CMS:RuntimeMinification:CacheBuster` is set to a fixed cache buster like `Version` or `AppDomain` when in production runtime mode;
- `ModelsBuilderModeValidator` - ensure `Umbraco:CMS:ModelsBuilder:ModelsMode` is not set to `InMemoryAuto` when in development runtime mode and set to `Nothing` when in production runtime mode;
This PR also fixes an issue with `DisableModelsBuilderNotificationHandler` not being correctly registered (causing the notification to not be handled) and removes a workaround added for .NET 6 Preview 1 (since we now require at least the stable .NET 6 version).
-------------------------
First test if everything still works when using `BackofficeDevelopment`, most notably whether you can use the in-memory generated models and update Razor views from the backoffice. If you've done this, you should have a document type, template and content rendered on the frontend, which can be used in the following steps.
Next, update `appsettings.Development.json` with the following settings:
```json
{
"Umbraco": {
"CMS": {
"Runtime": {
"Mode": "Development"
},
"ModelsBuilder": {
"ModelsMode": "SourceCodeAuto"
}
}
}
}
```
Ensure the models are generated by going to Settings - Models Builder - Generate models. You're now able to remove the `RazorCompileOnBuild` and `RazorCompileOnPublish` ~and `CopyRazorGenerateFilesToPublishDirectory`~ properties from the csproj-file (from the `Umbraco.Web.UI` project when testing from source). Running the application again should still show the rendered content, changing document types will need a manual recompile, but updates to Razor views will still be automatically recompiled.
Next either add a `appsettings.Production.json` file containing the settings below or have these set using environment variables/CLI arguments when running the application (make sure to update `UmbracoApplicationUrl` to the canonical URL of your Umbraco installation):
```json
{
"Umbraco": {
"CMS": {
"Runtime": {
"Mode": "Production"
},
"Global": {
"UseHttps": true
},
"ModelsBuilder": {
"ModelsMode": "Nothing"
},
"WebRouting": {
"UmbracoApplicationUrl": "https://localhost:5001/"
}
}
}
}
```
Now publish your application and test it by running it using production mode, you can use the following commands (start a PowerShell terminal in the repository root):
```powershell
# Publish application (make sure you exit any running instances of Umbraco.Web.UI)
Push-Location src\Umbraco.Web.UI
dotnet publish --configuration Release
# Copy database and media to publish output
New-Item bin\Release\net6.0\publish\umbraco\Data\ -Type Directory
Copy-Item umbraco\Data\*.* bin\Release\net6.0\publish\umbraco\Data\
Copy-Item wwwroot\media\ bin\Release\net6.0\publish\wwwroot\media\ -Recurse
# Run application
Push-Location bin\Release\net6.0\publish
./Umbraco.Web.UI.exe
```
If you didn't create the `appsettings.Production.json` file, you can change the last command to: `./Umbraco.Web.UI.exe Umbraco:CMS:Runtime:Mode=Production Umbraco:CMS:Global:UseHttps=true Umbraco:CMS:ModelsBuilder:ModelsMode=Nothing Umbraco:CMS:WebRouting:UmbracoApplicationUrl=https://localhost:5001/`.
You should see the rendered content again, but changes to either document types or Razor views won't be applied, because that will require republishing from source.
_Note: Testing the published output (instead of changing the environment name to Production and building the source in Release mode) ensures you also test whether everything still works after removing the `RazorCompileOnPublish` ~and `CopyRazorGenerateFilesToPublishDirectory`~ property (as that only affects the publish output)._
-------------------------------
The following improvements can be done after merging this PR:
- Add a health check that returns a notification/warning when not using the Production runtime mode on your production environment;
- Add runtime mode to system information dialog and telemetry data;
- Disable backoffice edits on document types, media types, member types, data types and templates when in production runtime mode (as those all require recompiling/republishing from source). This should be done at the UI/backoffice controller level, as the service APIs will still need to be able to update your database structure, e.g. so Umbraco Deploy can still deploy metadata changes.
opened 10:53AM - 18 Jul 22 UTC
status/idea
category/dx
type/bug
type/feature
### Which *exact* Umbraco version are you using? For example: 9.0.1 - don't just… write v9
v10.1.0 RC
### Bug summary
Firstly, [this new feature in 10.1](https://github.com/umbraco/Umbraco-CMS/pull/12631) is great!
I came here needing Razor runtime compilation disabled, and my problem is half solved (🎉), but the only way to disable it is to use the "production" runtime mode. The production mode enforces settings that are not right for my environment (it's not a _production_ environment).
It would be helpful to be able to disable Razor runtime compilation independently of the runtime mode - perhaps as its own setting that the production mode can then validate, like the others?
### Steps to reproduce
Install Umbraco 10.1.0 RC.
Use "development" runtime mode.
Razor runtime compilation is enabled, with no option to turn off.
### Expected result / actual result
Razor runtime compilation to be configurable independently of other environment specific settings.
Saeve
October 3, 2025, 6:55pm
4
Awesome references!
To recap what I, think, I know so far about the razor pages in production.
Following Umbraco best practice one should pre-compile views for prod
The actual razor page(.cshtml) should not be included in the output for prod
Running Umbraco in production mode should disable viewing and editing of the razor pages
What I really want to know is how Umbraco interacts with the razor pages in production mode and everything pre-compiled.
Say I SSH into a server that is in production mode and has the razor pages compiled and part of the binary.
If I create a Razor file with the same name in the same location, would that really take priority over the one inside the DLL?
Also how is this option in my .csproj needed for backoffice to function?
<PropertyGroup>
<!-- Razor files are needed for the backoffice to work correctly -->
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
</PropertyGroup>
From what I can see my razor files are actually not present in prod, but this comment states otherwise.
Is it just a case of this is required when not in production mode
Does this mean that all Umbraco sites running in production mode suffers from this, even when the razor pages are part of the same DLL?
JasonElkin
(Jason Elkin)
October 8, 2025, 9:38am
5
This is what I’m not sure about. The behaviour of the Templates in the Backoffice is kind of broken without these files, and it really doesn’t matter if you do include them on prod. The question is if you care about that feature looking wrong.
Kevin’s posted some screenshots of what happens on this related post .
From what I’ve seen, yes. It’s not a massive problem - but if you’re trying to run Umbraco in certain high-performance scenarios it can become noticeable.
JasonElkin
(Jason Elkin)
December 17, 2025, 10:32am
6
HQ did fix this, and in time for v17!
In v17, if you remove the reference to `Umbraco.Cms.DevelopmentMode.Backoffice ` in new installs, or don’t add it in upgrades, then the dependency on Razor Runtime Compilation is gone.
More details in the Version Specific Upgrade notes in the docs:
1 Like
Saeve
December 18, 2025, 11:29am
7
Oh damn!
I definitely have to play around with V17 soon.