0

在 ASP.NET Core 2.2 中渲染 RazorPage 时工作得非常好,直到我添加一个部分标记,当我在浏览器中打开它时它工作正常,但当我使用 RazorPageToStringRenderer 调用它时失败,并出现以下错误:

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

这是我的 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();
    }
}

问题的关键部分是我的 RazorPage 位于 RazorClassLibrary 中,并且它的路径是 Areas/Email/Pages/ConfirmEmail.cshtml。我也有一个 ViewImports.cshtml ,但我认为它没有正确加载它。

我尝试设置 ViewContext 的 ExecutingFilePath 属性,但这没有任何区别。

事实:页面:RCL\Areas\Email\Pages\ConfirmEmail.cshtml 我使用此行呈现部分页面:

<partial name="_EmailButton" model="Model.ButtonModel"/>

部分:RCL\Areas\Email\Pages\Shared_EmailButton.cshtml

我已经推送了一个在此处重现问题的示例项目:https ://github.com/paulcsiki/TestRCLToString 。

4

1 回答 1

0

一种可行的解决方法是使用 RCL\Areas\Email\Pages\ConfirmEmail.cshtml 中部分页面的完整路径。

从:

<partial name="_EmailButton" model="Model.ButtonModel"/>

至:

<partial name="/Areas/Email/Pages/Shared/_EmailButton.cshtml" model="Model.ButtonModel"/>
于 2018-12-08T23:15:03.323 回答