protected virtual async Task RenderPartialCoreAsync([NotNull] string partialViewName, TextWriter writer) { var viewEngineResult = _viewContext.ViewEngine.FindPartialView(ViewContext, partialViewName); if (!viewEngineResult.Success) { var locations = string.Empty; if (viewEngineResult.SearchedLocations != null) { locations = Environment.NewLine + string.Join(Environment.NewLine, viewEngineResult.SearchedLocations); } throw new InvalidOperationException($"Partial view {partialViewName} not found in {locations}."); } var view = viewEngineResult.View; using (view as IDisposable) { var viewContext = new ViewContext(_viewContext, view, _viewContext.ViewData, writer); await viewEngineResult.View.RenderAsync(viewContext); } }
public HtmlHelper(ViewContext viewContext) { _viewContext = viewContext; }
public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context) { IRazorPageFactory pageFactory = new VirtualPathRazorPageFactory(context, _basePageType); List<IDocument> validInputs = inputs .Where(x => _ignorePrefix == null || !x.ContainsKey(Keys.SourceFileName) || !x.FilePath(Keys.SourceFileName).FullPath.StartsWith(_ignorePrefix)) .ToList(); // Compile the pages in parallel ConcurrentDictionary<IDocument, Tuple<ViewContext, ViewEngineResult>> compilationResults = new ConcurrentDictionary<IDocument, Tuple<ViewContext, ViewEngineResult>>(); Parallel.ForEach(validInputs, x => { Trace.Verbose("Compiling Razor for {0}", x.SourceString()); IViewStartProvider viewStartProvider = new ViewStartProvider(pageFactory, _viewStartPath?.Invoke<FilePath>(x, context)); IRazorViewFactory viewFactory = new RazorViewFactory(viewStartProvider); IRazorViewEngine viewEngine = new RazorViewEngine(pageFactory, viewFactory); ViewContext viewContext = new ViewContext(null, new ViewDataDictionary(), null, x, context, viewEngine); ViewEngineResult viewEngineResult; using (Stream stream = x.GetStream()) { viewEngineResult = viewEngine.GetView(viewContext, GetRelativePath(x), stream).EnsureSuccessful(); } compilationResults[x] = new Tuple<ViewContext, ViewEngineResult>(viewContext, viewEngineResult); }); // Now evaluate them in sequence - have to do this because BufferedHtmlContent doesn't appear to work well in multi-threaded parallel execution TaskScheduler exclusiveScheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler; CancellationToken cancellationToken = new CancellationToken(); return validInputs .Select(input => { using (Trace.WithIndent().Verbose("Processing Razor for {0}", input.SourceString())) { Tuple<ViewContext, ViewEngineResult> compilationResult; if (compilationResults.TryGetValue(input, out compilationResult)) { using (StringWriter writer = new StringWriter()) { compilationResult.Item1.View = compilationResult.Item2.View; compilationResult.Item1.Writer = writer; Task.Factory.StartNew(() => compilationResult.Item2.View.RenderAsync(compilationResult.Item1), cancellationToken, TaskCreationOptions.None, exclusiveScheduler).Unwrap().GetAwaiter().GetResult(); return context.GetDocument(input, writer.ToString()); } } Trace.Warning("Could not find compilation result for {0}", input.SourceString()); return null; } }); }