Render Razor View(.cshtml) to String in .NET Core

Supports .NET Core 3.1+, .NET 5+, .NET 6, .NET 7, .NET 8— Console, ASP.NET Core Web/Api, Worker Service, WPF/WinForms(.NET Core) Applications

Soundar Anbu
4 min readApr 26, 2020

In most projects, there might be one or many of the following requirements.

  • Generate invoices, reports, bank statements, resume in HTML & later convert it to PDF or send in email
  • Send emails to multiple users with HTML-rich dynamic email content with varying data and more.
  • Generate files from template
  • Do the above in a separate worker service.

Generating the HTML string inside the code will be messy. Many popular frameworks have a template engine to do so. Similarly ASP.NET Core has Razor. But rendering the string out of a Razor view(.cshtml) is not straightforward in both ASP.NET Core Web Application or Console Application.

There are a few popular libraries available for this purpose. However, I remain unconvinced by them because they are either slow, lack essential view features (such as view engines, views, view components, and HTML helpers), require several lines of code, or do not fully support both web applications and console applications, especially in .NET Core 3.0+.

Razor.Templating.Core to the rescue. I had to create this library out of extreme need.

Let’s get started…

In this tutorial, I’m going to render the HTML string for the Invoice from .cshtml. The source code can be found here.

Creating Razor Class Library:

Let’s create the razor class library project which will house the .cshtml files.

  • In Visual Studio 2019 (v16.6.3 — latest version preferred), create a new “Razor Class Library” (.NET Core) Project. Let’s name it ‘ Razor.Templates’.
Create New ‘Razor Class Library’ Project
  • If we look at the Razor.Templates.csproj, note that Sdk=”Microsoft.NET.Sdk.Razor”. This will use the Razor SDK to precompile the .cshtml files to <Your-Project-Name>.Views.dll
  • Make sure the Property Group contains <AddRazorSupportForMvc>true</AddRazorSupportForMvc>. Otherwise, add it.
  • Also, please ensure <FrameworkReference Include=”Microsoft.AspNetCore.App” /> is present.
Invoice.cs
  • If we build the ‘Razor.Templates’ project, we can see the razor view is precompiled to ‘Razor.Templates.Views.dll’.
  • So far we’ve created our Razor Class Library
  • Note: In .NET 6, views are compiled to the same dll as the project. No separate dll file is produced.

Rendering View to String in Console Application:

  • Create a new console application. Let’s name it ‘Razor.Templating.Example.Invoice’
  • Add a reference to ‘Razor.Templates’ project. -this is important. Otherwise, ‘View Not Found’ exception will be thrown.
  • Install the supported version of Razor.Templating.Core NuGet package.
  • For .NET 6, use v1.7.0+
Installing Razor.Templating.Core using Nuget package manager
  • Let’s construct the view model that needs to be passed to the razor view
Program.cs
  • Now call the magic line with the relative path to the .cshtml file & the view model object as parameters.
  • Always ensure that the .cshtml files are in a unique path when more than one razor class library is referenced.
  • No more wait… Let’s run the program!
Output
  • We’ve rendered the razor view(.cshtml) file on the fly with just one line of code in a console application.
  • The same works for the ASP.NET Core Web application, ASP.NET Core Web API, Worker Service, and even WPF/WinForms(.NET Core) application. Look for the examples here.
  • Further, we can extend this to send emails, create PDF from HTML, and more.

Dependency Injection: [Since v1.4.0]

If you need to inject dependencies into your views, we can leverage the inbuilt DI system in .NET Core. Find the example project here

For ASP.NET Core Applications, in Startup.cs class, register dependencies as below:

Now anywhere from your application, render the view as usual using the static class:

Render .cshtml string using the RazorTemplateEngine static class

or inject the object using IRazorTemplateEngine interface in the constructor or parameter (from v1.8.0):

Injecting RazorTemplateEngine object using IRazorTemplateEngine interface

Inject.cshtml looks like below:

For Console Applications, use DI as below:

Look for a reference here.

GitHub Repository: https://github.com/soundaranbu/RazorTemplating

NuGet Package: https://www.nuget.org/packages/Razor.Templating.Core

Support:

If you find this helpful, consider supporting the development of this library with one or more coffee ;) Thanks!

--

--