title: Programmatically render Razor Page as HTML string
body: <h1>Goal</h1>
  <ul>
  <li>I'm trying to generate a HTML string on the backend as I want to
  convert it to a PDF using a HtmlToPDF library.</li>
  <li>I also want to be able to easily see the generated HTML in the browser, for debugging/tweaking purposes. The page will only be public when <code>IsDevelopment()</code>.</li>
  <li>I want it to be as simple as possible.</li>
  </ul>
  <p>I'm using ASP.NET Core 3.1</p>
  <h1>Approach</h1>
  <h2>Razor Page</h2>
  <p>I figured I'd try the <em>new</em> Razor Pages as they're advertised as super easy.</p>
  <pre class="lang-html prettyprint-override"><code>@page
  @using MyProject.Pages.Pdf
  @model IndexModel
  
  &lt;h2&gt;Test&lt;/h2&gt;
  &lt;p&gt;
      @Model.Message
  &lt;/p&gt;
  </code></pre>
  <pre class="lang-cs prettyprint-override"><code>namespace MyProject.Pages.Pdf
  {
      public class IndexModel : PageModel
      {
          private readonly MyDbContext _context;
  
          public IndexModel(MyDbContext context)
          {
              _context = context;
          }
  
          public string Message { get; private set; } = &quot;PageModel in C#&quot;;
  
          public async Task&lt;IActionResult&gt; OnGetAsync()
          {
              var count = await _context.Foos.CountAsync();
  
              Message += $&quot; Server time is { DateTime.Now } and the Foo count is { count }&quot;;
  
              return Page();
          }
      }
  }
  </code></pre>
  <p>This works in the browser - yay!</p>
  <h2>Render and get HTML string</h2>
  <p>I found <a href="https://stackoverflow.com/questions/46540358/render-a-razor-page-to-string">Render a Razor Page to string</a> which appears to do what I want.</p>
  <p>But this is where the trouble start :(</p>
  <h1>Problems</h1>
  <p>First off, I find it very odd that when you find the page via <code>_razorViewEngine.FindPage</code> it doesn't know how to populate the <code>ViewContext</code> or the <code>Model</code>. I'd think the job of <code>IndexModel</code> was to populate these. I was hoping it was possible to ask ASP.NET for the <code>IndexModel</code> Page and that would be that.</p>
  <p>Anyway... the next problem. In order to render the Page I have to manually create a <code>ViewContext</code> and I have to supply it with a <code>Model</code>. But the Page is the Model, and since it's a Page it isn't a simple ViewModel. It rely on DI and it expects <code>OnGetAsync()</code> to be executed in order to populate the Model. It's pretty much a catch-22.</p>
  <p>I also tried fetching the View instead of the Page via <code>_razorViewEngine.FindView</code> but that also requires a Model, so we're back to catch-22.</p>
  <p>Another issue. The purpose of the debug/tweaking page was to easily see what was generated. But if I have to create a <code>Model</code> outside <code>IndexModel</code> then it's no longer representative of what is actually being generated in a service somewhere.</p>
  <p>All this have me wondering if I'm even on the right path. Or am I missing something?</p>