private async Task<StringCollectionTextWriter> RenderPageAsync(IRazorPage page, ViewContext context, bool executeViewStart) { var bufferedWriter = new StringCollectionTextWriter(context.Writer.Encoding); var writer = (TextWriter)bufferedWriter; // The writer for the body is passed through the ViewContext, allowing things like HtmlHelpers // and ViewComponents to reference it. var oldWriter = context.Writer; var oldFilePath = context.ExecutingFilePath; context.Writer = writer; context.ExecutingFilePath = page.Path; try { if (executeViewStart) { // Execute view starts using the same context + writer as the page to render. await RenderViewStartAsync(context); } await RenderPageCoreAsync(page, context); return bufferedWriter; } finally { context.Writer = oldWriter; context.ExecutingFilePath = oldFilePath; writer.Dispose(); } }
public async Task<IHtmlContent> PartialAsync( [NotNull] string partialViewName) { using (var writer = new StringCollectionTextWriter(Encoding.UTF8)) { await RenderPartialCoreAsync(partialViewName, writer); return writer.Content; } }
private async Task RenderLayoutAsync(ViewContext context, StringCollectionTextWriter bodyWriter) { // A layout page can specify another layout page. We'll need to continue // looking for layout pages until they're no longer specified. var previousPage = RazorPage; var renderedLayouts = new List<IRazorPage>(); while (!string.IsNullOrEmpty(previousPage.Layout)) { var layoutPage = GetLayoutPage(context, previousPage.Layout); // Notify the previous page that any writes that are performed on it are part of sections being written // in the layout. previousPage.IsLayoutBeingRendered = true; layoutPage.PreviousSectionWriters = previousPage.SectionWriters; layoutPage.RenderBodyDelegate = bodyWriter.CopyTo; bodyWriter = await RenderPageAsync(layoutPage, context, executeViewStart: false); renderedLayouts.Add(layoutPage); previousPage = layoutPage; } // Ensure all defined sections were rendered or RenderBody was invoked for page without defined sections. foreach (var layoutPage in renderedLayouts) { layoutPage.EnsureRenderedBodyOrSections(); } await bodyWriter.CopyToAsync(context.Writer); }