/// <summary> /// Gets the Razor page for an input document stream. This is roughly modeled on /// DefaultRazorPageFactory and CompilerCache. Note that we don't actually bother /// with caching the page if it's from a live stream. /// </summary> private IRazorPage GetPageFromStream(IServiceProvider serviceProvider, RenderRequest request) { string relativePath = request.RelativePath; if (relativePath.StartsWith("~/", StringComparison.Ordinal)) { // For tilde slash paths, drop the leading ~ to make it work with the underlying IFileProvider. relativePath = relativePath.Substring(1); } // Get the file info by combining the stream content with info found at the document's original location (if any) IHostingEnvironment hostingEnvironment = serviceProvider.GetRequiredService <IHostingEnvironment>(); IFileInfo fileInfo = new StreamFileInfo(hostingEnvironment.WebRootFileProvider.GetFileInfo(relativePath), request.Input); RelativeFileInfo relativeFileInfo = new RelativeFileInfo(fileInfo, relativePath); // Compute a hash for the content since pipelines could have changed it from the underlying file // We have to pre-compute the hash (I.e., no CryptoStream) since we need to check for a hit before reading/compiling the view byte[] hash = MD5.Create().ComputeHash(request.Input); request.Input.Position = 0; CompilerCacheResult compilerCacheResult = CompilePage(serviceProvider, request, hash, relativeFileInfo, relativePath); IRazorPage result = compilerCacheResult.PageFactory(); return(result); }
/// <summary> /// Gets the Razor page for an input document stream. This is roughly modeled on /// DefaultRazorPageFactory and CompilerCache. Note that we don't actually bother /// with caching the page if it's from a live stream. /// </summary> private IRazorPage GetPageFromStream( string relativePath, string viewStartLocation, string layoutLocation, Stream stream, IFileProvider rootFileProvider, IRazorCompilationService razorCompilationService) { if (relativePath.StartsWith("~/", StringComparison.Ordinal)) { // For tilde slash paths, drop the leading ~ to make it work with the underlying IFileProvider. relativePath = relativePath.Substring(1); } // Get the file info by combining the stream content with info found at the document's original location (if any) IFileInfo fileInfo = new StreamFileInfo(rootFileProvider.GetFileInfo(relativePath), stream); RelativeFileInfo relativeFileInfo = new RelativeFileInfo(fileInfo, relativePath); // Try to get the compilation from the cache, but only if the stream is empty // Cache key is relative path if no explicit view start or layout OR either/both of those if specified CompilationResult compilationResult = stream.Length == 0 ? _compilationCache.GetOrAdd( viewStartLocation == null ? (layoutLocation ?? relativePath) : (layoutLocation == null ? viewStartLocation : viewStartLocation + layoutLocation), _ => GetCompilation(relativeFileInfo, razorCompilationService)) : GetCompilation(relativeFileInfo, razorCompilationService); // Create and return the page // We're not actually using the ASP.NET cache, but the CompilerCacheResult ctor contains the logic to create the page factory CompilerCacheResult compilerCacheResult = new CompilerCacheResult(relativePath, compilationResult, Array.Empty <IChangeToken>()); return(compilerCacheResult.PageFactory()); }
/// <summary> /// Gets the Razor page for an input document stream. This is roughly modeled on /// DefaultRazorPageFactory and CompilerCache. Note that we don't actually bother /// with caching the page if it's from a live stream. /// </summary> private IRazorPage GetPageFromStream(string relativePath, Stream stream, IFileProvider rootFileProvider, IRazorCompilationService razorCompilationService) { if (relativePath.StartsWith("~/", StringComparison.Ordinal)) { // For tilde slash paths, drop the leading ~ to make it work with the underlying IFileProvider. relativePath = relativePath.Substring(1); } // Get the file info by combining the stream content with info found at the document's original location (if any) IFileInfo fileInfo = new StreamFileInfo(rootFileProvider.GetFileInfo(relativePath), stream); RelativeFileInfo relativeFileInfo = new RelativeFileInfo(fileInfo, relativePath); // Create the compilation CompilationResult compilationResult = razorCompilationService.Compile(relativeFileInfo); compilationResult.EnsureSuccessful(); // Create and return the page // We're not actually using the cache, but the CompilerCacheResult ctor contains the logic to create the page factory CompilerCacheResult compilerCacheResult = new CompilerCacheResult(relativePath, compilationResult, Array.Empty <IChangeToken>()); return(compilerCacheResult.PageFactory()); }