I have been working on this sporadically since I asked the question nearly two years ago, and I believe I have a 99% non-clunky solution. Everything below works for me in Visual Studio 16.4.5.
Here's what I have learned about getting Razor to work in console and library projects.
- Everything seems to work with the least trouble if create and consume your Razor files in a .NET Core console app.
- You can also put your Razor files in a .NET Standard library and consume them from a .NET Core console app, though in this case there is some minor ugliness in Solution Explorer. I don't think it has any effect on functionality, however.
- Either way, both the
@model
and the @using
keywords work correctly, Intellisense works correctly, lambda expressions work correctly, everything seems to work properly.
Here's what you have to do:
To add a Razor file:
Add a new HTML file, but name the file with a .cshtml
extension.
Select the file in Solution Explorer. In the Properties window, under Custom Tool, enter RazorTemplatePreprocessor
. A .cs
file will immediately be generated.
To consume the generated class:
var razor = new MyRazorClass();
razor.Model = "Hello from Razor"; // Assumes @model string in the Razor file; custom classes are fine too.
var html = razor.GenerateString();
Console.WriteLine(html);
To resolve the errors in the Error List (which incidentally do not seem to affect functionality but certainly create mental clutter):
Add NuGet references to:
Microsoft.AspNetCore.Mvc.Core
Microsoft.AspNetCore.Mvc.Razor
If you are adding your Razor files to a .NET Standard library, you'll get a bunch of the following errors:
Feature 'nullable reference types' is not available in C# 7.3. Please use language version 8.0 or greater.
To fix this, add the following two lines to the project file:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Nullable>enable</Nullable> <!-- Add this line -->
<LangVersion>8.0</LangVersion> <!-- Add this line -->
</PropertyGroup>
At this point, the project should compile with no errors or warnings!
However, it doesn't work perfectly. There some oddities, which give me some concern that things might unexpectedly break on me in the future.
These problems only seem to occur when using Razor files from .NET Standard libraries:
- The Solution Explorer sometimes shows the descendants of the
.cshtml
file in two different ways:
a. In what I believe is the correct way, the .cshtml
file has as its only descendant a generated .cs
file. That file in turn has two generated classes, YourRazorClass
and YourRazorClassBase
. Each of those can be expanded to show the class members, which have nice, human-readable names.
b. Sometimes, however, an underscore-prefixed class appears as a direct descendant of the .cshtml
file (e.g., _MyTestRazorClass
), Also, its class members are different.
This seems to appear and disappear from the Solution Explorer and I don't think it causes any harm, but it certainly causes some mental clutter as you wonder what on earth is going on.
- In Solution Explorer, under the
[Project Name]
> Dependencies
> Analyzers
, there are a bunch of warnings that get propagated up into the same section of any project that consumes the library. This also creates mental clutter. Fortunately, you can turn these off by doing the following:
a. Right-click the project and choose Properties
.
b. Under Code Analysis
, uncheck the Run on Build
and Run on Live Analysis
boxes.
One final note: I have not yet tested using a .NET Standard library set up in this way inside a Xamarin project yet (this is the scenario that originally had me going down this road), but I will do so in the future and update
this answer at that time.
UPDATE: I have now used this technique in a released Xamarin app! The only weirdness is that you can't copy-paste .cshtml files to create a new one. It screws up both the original file and the copy and you have to go edit the project file to fix things. Instead, just manually add a new file as described above each time.
I hope this helps someone. And if anyone figures out what is going on with the weirdness in Solution Explorer, I would love to know!