从RazorClassLibrary将RazorPage渲染为字符串无法渲染部分

时间:2018-12-08 21:38:01

标签: razor asp.net-core razor-pages razor-class-library

在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

1 个答案:

答案 0 :(得分:0)

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

发件人:

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

收件人:

<partial name="/Areas/Email/Pages/Shared/_EmailButton.cshtml" model="Model.ButtonModel"/>