When rendering a RazorPage in ASP.NET Core 2.2 works perfectly fine until I add a partial tag which works fine when I open it in the browser but fails when I call it using RazorPageToStringRenderer with the following error:
InvalidOperationException: The partial view '_EmailButton' was not found. The following locations were searched:
/Views/Home/_EmailButton.cshtml
/Views/Shared/_EmailButton.cshtml
/Pages/Shared/_EmailButton.cshtml
Here's my RazorPageToStringRenderer:
public async Task<string> RenderToStringAsync<T>(string pageName, T model) where T : PageModel
{
var context = new ActionContext(
httpContext.HttpContext,
httpContext.HttpContext.GetRouteData(),
actionContext.ActionContext.ActionDescriptor
);
using (var sw = new StringWriter())
{
var result = razorViewEngine.GetPage(null, pageName);
if (result.Page == null)
throw new ArgumentNullException($"The page {pageName} cannot be found.");
var view = new RazorView(razorViewEngine,
activator,
new List<IRazorPage>(),
result.Page,
HtmlEncoder.Default,
new DiagnosticListener("ViewRenderService"));
var viewContext = new ViewContext(
context,
view,
new ViewDataDictionary<T>(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = model
},
new TempDataDictionary(
httpContext.HttpContext,
tempDataProvider
),
sw,
new HtmlHelperOptions()
);
viewContext.ExecutingFilePath = pageName;
var page = (Page) result.Page;
page.PageContext = new PageContext
{
ViewData = viewContext.ViewData
};
page.ViewContext = viewContext;
activator.Activate(page, viewContext);
await page.ExecuteAsync();
return sw.ToString();
}
}
The key part of the issue is the fact that my RazorPage is in a RazorClassLibrary and it's path is Areas/Email/Pages/ConfirmEmail.cshtml. I do have a ViewImports.cshtml there too but I don't think it's loading it correctly.
I've tried setting the ExecutingFilePath property of the ViewContext but that didn't make any difference.
Facts: Page: RCL\Areas\Email\Pages\ConfirmEmail.cshtml I render the partial page using this line:
<partial name="_EmailButton" model="Model.ButtonModel"/>
Partial: RCL\Areas\Email\Pages\Shared_EmailButton.cshtml
I've pushed a sample project which reproduces the issue over here: https://github.com/paulcsiki/TestRCLToString.