简体   繁体   中英

What is the best way to use Razor in a console application

I know similar questions have been asked before, but the only answers are six years old, and the projects people refer to seem like they're not being maintained.

I want to use Razor in a console app or a class library to render HTML. I would also like to have working Intellisense in the .cshtml files.

Currently, I am able to jury-rig this by doing the following:

  • Create console app.
  • Add .cshtml file.
  • In Properties, set the Custom Tool property to RazorTemplatePreprocessor

This causes Razor syntax to be recognized. So if you have Test.cshtml , it generates a class called Test that you can use like so:

var test = new Test();
test.Model = "Hi there";
var html = test.GenerateString();

Console.WriteLine(html);

This is just about good enough for my purposes. However, the actual coding experience within the .cshtml file is pretty broken:

  • There are red squigglies all over the place complaining about:
  • Not being able to use var because it's C# 2.
  • Saying the type or namespace of various types can't be found.
  • The above is especially true of types imported from other libraries.
  • The @model keyword is not recognized.
  • Intellisense sometimes works, sometimes doesn't.

Weirdly, if you just ignore all of these errors, the HTML is actually generated correctly, including use of the libraries and @model keyword that the Razor engine complained about. However, this causes major mental clutter because if you have any number of .cshtml files, you very quickly get into hundreds and thousands of these errors mixed in with real errors.

Is there anything I can do to cause the actual Razor coding experience to work more like it does in an ASP.NET web app?

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.

  1. Everything seems to work with the least trouble if create and consume your Razor files in a .NET Core console app.
  2. 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.
  3. 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:

  1. 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 (eg, _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.

  1. 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!

Just use RazorEngine library.

cshtml file intellisense is supported as per documentation.

I usually use T4 Templates outside ASP.NET app: https://msdn.microsoft.com/en-US/library/bb126445.aspx . There are several plugins for Visual Studio which enable code highlighting, for example http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html .

Of course, T4 is not equivalent to Razor and you should learn syntax in order to use it, but I think using Razor outside webapp is bad style...

Using T4 you can create from templates your own classes with custom strongly typed properties and constructors, and that's much more than Razor can.

You can upgrade to C#4 by adding the nuget packgage:

Microsoft.CodeDom.Providers.DotNetCompilerPlatform

This will give you the var keyword.

Also, you can get intellisense for your template parameters doing the following

  1. Create a new .cs file
  2. Inside it, add a partial class with the same name as the one automaticaly generated by the .cshtml file. Something like that:

public partial class htmlRazor : htmlRazorBase { public DateTime myDate}

  1. Add a constructor to this partial class that will take some input parameters:

public htmlRazor(DateTime _mydate) {myDate = _mydate}

  1. Add the following lines at the top of your .cshtml file:

@using yourNameSpace @*Make sure the parameter below have exactly the same name as the variable inside the partial class (public DateTime myDate). This line will be full of errors, but you can safely ignore them.*@ @{htmlRazor agrs = new htmlRazor(myDate);}

You can now access your parameters inside the razor code by doing agrs.myDate for exemple.

As a last note, my razor project is actualy a class library (creates a .dll file). I reference this library from a second console application project. I then create the html from the template like that:

htmlRazor html = new htmlRazor(DateTime.Now); string htmlTxt = html.GenerateString();

最好的方法是“RazorLight” https://github.com/toddams/RazorLight简单明了

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM