将多个Razor页面渲染到HTML

时间:2019-10-24 17:47:24

标签: asp.net-core razor-pages

我有一个在Razor Pages中使用Markdown的应用程序(使用自定义TagHelper编译)来显示静态内容。大约有300页。

我正在尝试将这些Razor页面呈现为html,以便我可以使用Lucene.net为内容建立索引,以便提供全文本搜索。

我设法创建了一些可以正常工作的代码(见下文),但是每当渲染后续页面时,都将添加之前渲染的内容。也就是说,当我渲染第一页时,它可以完美地工作,但是,当我渲染另一页时,也包括了第一页的内容;当我渲染第三页时,也包括了前两页的内容。

我尝试在方法中手动创建依赖项,并且尝试为每个页面创建此类的新实例,但始终具有相同的结果。

我想念什么?

public class RazorPageRenderer
{
    private readonly IRazorViewEngine razorViewEngine;
    private readonly ITempDataProvider tempDataProvider;
    private readonly IHttpContextAccessor httpContextAccessor;
    private readonly IActionContextAccessor actionContextAccessor;
    private readonly IRazorPageActivator razorPageActivator;
    private readonly ILogger logger;

    public RazorPageRenderer(
        IRazorViewEngine razorViewEngine,
        ITempDataProvider tempDataProvider,
        IHttpContextAccessor httpContextAccessor,
        IActionContextAccessor actionContextAccessor,
        IRazorPageActivator razorPageActivator,
        ILogger<RazorPageRenderer> logger)
    {
        this.razorViewEngine = razorViewEngine;
        this.tempDataProvider = tempDataProvider;
        this.httpContextAccessor = httpContextAccessor;
        this.actionContextAccessor = actionContextAccessor;
        this.razorPageActivator = razorPageActivator;
        this.logger = logger;
    }

    public async Task<string> RenderAsync(IRazorPage razorPage) => await RenderAsync<object>(razorPage, null);

    public async Task<string> RenderAsync<T>(IRazorPage razorPage, T model)
    {
        try
        {
            var viewDataDictionary = CreateViewDataDictionary(razorPage.GetType(), model);

            await using var writer = new StringWriter();
            var view = new RazorView(
                razorViewEngine,
                razorPageActivator,
                Array.Empty<IRazorPage>(),
                razorPage,
                HtmlEncoder.Default,
                new DiagnosticListener(nameof(RazorPageRenderer)));

            var viewContext = new ViewContext(
                actionContextAccessor.ActionContext,
                view,
                viewDataDictionary,
                new TempDataDictionary(
                    httpContextAccessor.HttpContext,
                    tempDataProvider),
                writer,
                new HtmlHelperOptions());

            if (razorPage is Page page)
            {
                page.PageContext = new PageContext(actionContextAccessor.ActionContext)
                {
                    ViewData = viewContext.ViewData
                };
            }

            razorPage.ViewContext = viewContext;

            razorPageActivator.Activate(razorPage, viewContext);

            await razorPage.ExecuteAsync();

            return writer.ToString();
        }
        catch (Exception exception)
        {
            logger.LogError(
                "An exception occured while rendering page: {Page}. Exception: {Exception}", 
                razorPage.Path, 
                exception);
        }
        return null;
    }

    private static ViewDataDictionary CreateViewDataDictionary(Type pageType, object model)
    {
        var dictionaryType = typeof(ViewDataDictionary<>)
            .MakeGenericType(pageType);
        var ctor = dictionaryType.GetConstructor(new[]
            {typeof(IModelMetadataProvider), typeof(ModelStateDictionary)});
        var viewDataDictionary = (ViewDataDictionary)ctor?.Invoke(
            new object[] {new EmptyModelMetadataProvider(), new ModelStateDictionary()});
        if (model != null && viewDataDictionary != null)
        {
            viewDataDictionary.Model = model;
        }
        return viewDataDictionary;
    }
}

0 个答案:

没有答案