/// <summary> /// Creates a new <see cref="CompiledViewDescriptor"/>. At least one of <paramref name="attribute"/> or /// <paramref name="item"/> must be non-<c>null</c>. /// </summary> /// <param name="item">The <see cref="RazorCompiledItem"/>.</param> /// <param name="attribute">The <see cref="RazorViewAttribute"/>.</param> public CompiledViewDescriptor(RazorCompiledItem item, RazorViewAttribute attribute) { if (item == null && attribute == null) { // We require at least one of these to be specified. throw new ArgumentException(Resources.FormatCompiledViewDescriptor_NoData(nameof(item), nameof(attribute))); } Item = item; // // For now we expect that MVC views and pages will still have either: // [RazorView(...)] or // [RazorPage(...)]. // // In theory we could look at the 'Item.Kind' to determine what kind of thing we're dealing // with, but for compat reasons we're basing it on ViewAttribute since that's what 2.0 had. ViewAttribute = attribute; // We don't have access to the file provider here so we can't check if the files // even exist or what their checksums are. For now leave this empty, it will be updated // later. ExpirationTokens = Array.Empty <IChangeToken>(); RelativePath = ViewPath.NormalizePath(item?.Identifier ?? attribute.Path); IsPrecompiled = true; }
private CompilationResult GetCompilation(RazorProjectItem projectItem, RazorProjectFileSystem projectFileSystem) { using (IServiceScope scope = _serviceScopeFactory.CreateScope()) { IServiceProvider serviceProvider = scope.ServiceProvider; // See RazorViewCompiler.CompileAndEmit() RazorProjectEngine projectEngine = serviceProvider.GetRequiredService <RazorProjectEngine>(); RazorCodeDocument codeDocument = projectEngine.Process(projectItem); RazorCSharpDocument cSharpDocument = codeDocument.GetCSharpDocument(); if (cSharpDocument.Diagnostics.Count > 0) { throw (Exception)CreateCompilationFailedException.Invoke( null, new object[] { codeDocument, cSharpDocument.Diagnostics }); } // Use the RazorViewCompiler to finish compiling the view for consistency with layouts IViewCompilerProvider viewCompilerProvider = serviceProvider.GetRequiredService <IViewCompilerProvider>(); IViewCompiler viewCompiler = viewCompilerProvider.GetCompiler(); Assembly assembly = (Assembly)CompileAndEmitMethod.Invoke( viewCompiler, new object[] { codeDocument, cSharpDocument.GeneratedCode }); // Get the runtime item RazorCompiledItemLoader compiledItemLoader = new RazorCompiledItemLoader(); RazorCompiledItem compiledItem = compiledItemLoader.LoadItems(assembly).SingleOrDefault(); return(new CompilationResult(compiledItem)); } }
private static async Task <string> GetOutput <TModel>(Assembly assembly, RazorCompiledItem razorCompiledItem, TModel model) { using (var output = new StringWriter()) { var compiledTemplate = assembly.GetType(razorCompiledItem.Type.FullName); var razorPage = (RazorPage)Activator.CreateInstance(compiledTemplate); if (razorPage is RazorPage <TModel> page) { AddViewData(page, model); } razorPage.ViewContext = new ViewContext { Writer = output }; razorPage.DiagnosticSource = new DiagnosticListener("GetOutput"); razorPage.HtmlEncoder = HtmlEncoder.Default; await razorPage.ExecuteAsync(); return(output.ToString()); } }
private static async Task <string> GetRenderedOutput <TModel>(RazorCompiledItem razorCompiledItem, TModel model) { using var stringWriter = new StringWriter(); var razorPage = GetRazorPageInstance(razorCompiledItem, model, stringWriter); await razorPage.ExecuteAsync(); return(stringWriter.ToString()); }
private static CompiledViewDescriptor GetCompiledViewDescriptor(RazorCompiledItem item) { var itemAssembly = item.Type.Assembly; var razorViewAttribute = itemAssembly.GetCustomAttributes <RazorViewAttribute>() .FirstOrDefault(attribute => attribute.ViewType == item.Type); return(new CompiledViewDescriptor(item, razorViewAttribute)); }
/// <summary> /// Gets the list of <see cref="IRazorSourceChecksumMetadata"/> associated with <paramref name="item"/>. /// </summary> /// <param name="item">The <see cref="RazorCompiledItem"/>.</param> /// <returns>A list of <see cref="IRazorSourceChecksumMetadata"/>.</returns> public static IReadOnlyList <IRazorSourceChecksumMetadata> GetChecksumMetadata(this RazorCompiledItem item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } return(item.Metadata.OfType <IRazorSourceChecksumMetadata>().ToArray()); }
/// <summary> /// Creates a new <see cref="CompiledViewDescriptor"/>. /// </summary> /// <param name="item">The <see cref="RazorCompiledItem"/>.</param> public CompiledViewDescriptor(RazorCompiledItem item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } Item = item; RelativePath = ViewPath.NormalizePath(item.Identifier); }
/// <summary> /// Creates a new <see cref="CompiledViewDescriptor"/>. /// </summary> /// <param name="item">The <see cref="RazorCompiledItem"/>.</param> public CompiledViewDescriptor(RazorCompiledItem item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } Item = item; ExpirationTokens = Array.Empty <IChangeToken>(); RelativePath = ViewPath.NormalizePath(item.Identifier); }
public WrappedRazorCompiledItem(RazorCompiledItem item) { _item = item; var assembly = _item.Type.Assembly.GetName().Name; if (assembly.EndsWith(".Views")) { assembly = assembly.Substring(0, assembly.Length - 6); } _identifier = $"/{assembly}{_item.Identifier}"; }
public static bool IsRecompilationSupported(RazorCompiledItem item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } // A Razor item only supports recompilation if its primary source file has a checksum. // // Other files (view imports) may or may not have existed at the time of compilation, // so we may not have checksums for them. var checksums = item.GetChecksumMetadata(); return(checksums.Any(c => string.Equals(item.Identifier, c.Identifier, StringComparison.OrdinalIgnoreCase))); }
private static RazorPage GetRazorPageInstance <TModel>(RazorCompiledItem razorCompiledItem, TModel model, TextWriter textWriter) { var razorPage = (RazorPage <TModel>)Activator.CreateInstance(razorCompiledItem.Type); razorPage.ViewData = new ViewDataDictionary <TModel>( new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }; razorPage.ViewContext = new ViewContext { Writer = textWriter }; razorPage.HtmlEncoder = HtmlEncoder.Default; return(razorPage); }
public async Task RunAsync(Assembly assembly, HttpContext httpContext, string viewName, object model) { try { RazorCompiledItemLoader loader = new RazorCompiledItemLoader(); RazorCompiledItem item = loader.LoadItems(assembly).SingleOrDefault(); EmbeddedViewModel view = (EmbeddedViewModel)Activator.CreateInstance(item.Type); view.HttpContext = httpContext; view.ViewName = viewName; view.Html = new Html(httpContext); view.Url = new Url(); if (model != null) { item.Type.GetProperty("Model").SetValue(view, model); } var result = await view.Execute(); if (httpContext.Response.StatusCode == 200 && result is EmbededViewViewResult) { await view.ExecuteAsync(); } if (httpContext.Response.StatusCode == 200 && result is EmbededViewJsonResult) { httpContext.Response.ContentType = "application/json"; await httpContext.Response.WriteAsync(((EmbededViewJsonResult)result).Json); } if (httpContext.Response.StatusCode == 200 && result is EmbededViewRedirectResult) { httpContext.Response.Redirect(((EmbededViewRedirectResult)result).Url); } } finally { BufferedStream bufferedStream = httpContext.Response.Body as BufferedStream; if (bufferedStream != null) { await bufferedStream.FlushAsync(); } } }
public HotReloadRazorCompiledItem(RazorCompiledItem previous, Type type) { _previous = previous; Type = type; }
public CompilationResult(RazorCompiledItem item) { CompiledItem = item; }
// Validates that we can use an existing precompiled view by comparing checksums with files on // disk. public static bool IsItemValid(RazorProjectFileSystem fileSystem, RazorCompiledItem item) { if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } if (item == null) { throw new ArgumentNullException(nameof(item)); } var checksums = item.GetChecksumMetadata(); // The checksum that matches 'Item.Identity' in this list is significant. That represents the main file. // // We don't really care about the validation unless the main file exists. This is because we expect // most sites to have some _ViewImports in common location. That means that in the case you're // using views from a 3rd party library, you'll always have **some** conflicts. // // The presence of the main file with the same content is a very strong signal that you're in a // development scenario. var primaryChecksum = checksums .FirstOrDefault(c => string.Equals(item.Identifier, c.Identifier, StringComparison.OrdinalIgnoreCase)); if (primaryChecksum == null) { // No primary checksum, assume valid. return(true); } var projectItem = fileSystem.GetItem(primaryChecksum.Identifier, fileKind: null); if (!projectItem.Exists) { // Main file doesn't exist - assume valid. return(true); } var sourceDocument = RazorSourceDocument.ReadFrom(projectItem); if (!string.Equals(sourceDocument.GetChecksumAlgorithm(), primaryChecksum.ChecksumAlgorithm, StringComparison.OrdinalIgnoreCase) || !ChecksumsEqual(primaryChecksum.Checksum, sourceDocument.GetChecksum())) { // Main file exists, but checksums not equal. return(false); } for (var i = 0; i < checksums.Count; i++) { var checksum = checksums[i]; if (string.Equals(item.Identifier, checksum.Identifier, StringComparison.OrdinalIgnoreCase)) { // Ignore primary checksum on this pass. continue; } var importItem = fileSystem.GetItem(checksum.Identifier, fileKind: null); if (!importItem.Exists) { // Import file doesn't exist - assume invalid. return(false); } sourceDocument = RazorSourceDocument.ReadFrom(importItem); if (!string.Equals(sourceDocument.GetChecksumAlgorithm(), checksum.ChecksumAlgorithm) || !ChecksumsEqual(checksum.Checksum, sourceDocument.GetChecksum())) { // Import file exists, but checksums not equal. return(false); } } return(true); }