Rendering an ASP.NET Core MVC action to a string

I’m currently going through my “build a static site engine” phase that most developers pass through at some point in their career. As part of this, I wanted to write a normal ASP.NET Core application complete with server-side rendering, and then have the option to entirely pre-render it to disk.

It turns out that this is quite difficult – StackOverflow and GitHub issues were a barren wasteland of half-working answers. Most everyone assumes that you have a ControllerContext, or at least an HttpContext! Rendering it from a command line application was unheard of!

After much experimentation, I managed to get it working! You can see a complete example in the RazorToStringExample repository.

For example, here’s how you can render the route Home/Index to a string:

public static class Program
    public static async Task Main(string[] args) // async Main requires C# 7.1
        var website = CreateWebHostBuilder(args).Build();

        // invoke your route to get the model result.
        var model = ((ViewResult)new HomeController().Index()).Model;

        // render the view with the model
        // must be scoped due to an internal IViewBufferScope service being scoped
        using (var scope = website.Services.CreateScope())
            var renderer = scope.ServiceProvider.GetService(typeof(RazorViewToStringRenderer)) as RazorViewToStringRenderer;
            var html = await renderer.RenderViewToStringAsync("Home/Index", model);

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

The magic happens in the RazorViewToStringRenderer, which is defined here. We have to set up a lot of ASP.NET Core services to get everything working, but so far it’s handled everything I’ve been able to throw at it!

tagged as, dotnet, razor and csharp