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