Type CompileView(string viewPath, IEnumerable <string> fullJsPaths, IEnumerable <string> fullCssPaths, IEnumerable <string> fullViewPaths) { log.Debug($"CompileView {viewPath} - JS Files: {JsonConvert.SerializeObject(fullJsPaths)} - CSS Files: {JsonConvert.SerializeObject(fullCssPaths)} - ViewFiles: {JsonConvert.SerializeObject(fullViewPaths)}"); var builder = new StringBuilder(); this.AppendHtml(fullViewPaths, builder); this.AppendJavascript(fullJsPaths, builder); // assumes viewPath is of the form "~/areas/{areaName}/path.cshtml var areaName = viewPath.Substring(8, viewPath.IndexOf("/", 8) - 8); this.AppendCss(fullCssPaths, areaName, builder); var viewCompilationData = new RazorViewCompilationData { Namespace = Path.GetDirectoryName(viewPath.Substring(2)).Replace("\\", ".").Replace("/", "."), ClassName = RazorViewCompiler.GetSafeClassName(Path.GetFileName(viewPath)), FilePath = viewPath, ViewContents = builder.ToString() }; var compiled = this.compiler.CompileFile(viewCompilationData); return(compiled); }
RazorCSharpDocument GenerateCSharp(RazorViewCompilationData view) { var sourceDocument = RazorSourceDocument.Create(view.ViewContents, view.FilePath, Encoding.UTF8); var codeDocument = RazorCodeDocument.Create(sourceDocument, this.defaultImports); codeDocument.Items.Add("ViewCompilationData", view); var razorCSharpDocument = this.razorTemplateEngine.GenerateCode(codeDocument); return(razorCSharpDocument); }
Type CompileCSharp(RazorViewCompilationData view, string source, RazorCSharpDocument razorCSharpDocument) { var cSharpCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); var compilation = CSharpCompilation.Create("assembly", new[] { CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode, path: view.FilePath, encoding: Encoding.UTF8) }, this.referenceAssemblies, cSharpCompilationOptions); log.Debug("Compiling {viewPath} - 1 of 3 log entries - Broken into entries 3 due to Seq raw payload limits. If you don't see log parts 2 and/or 3. They're too big, soz", view.FilePath); log.Debug("Compiling {viewPath} - 2 of 3 log entries - Source {source}", view.FilePath, source); log.Debug("Compiling {viewPath} - 3 of 3 log entries - GeneratedCode {generatedCode}", view.FilePath, razorCSharpDocument.GeneratedCode); using (var assemblyStream = new MemoryStream()) using (var symbolStream = new MemoryStream()) { var result = compilation.Emit(assemblyStream, symbolStream); var errors = result.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).ToArray(); if (errors.Any()) { var message = errors.Select(e => { var fileLinePositionSpan = e.Location.GetMappedLineSpan(); return($"[{e.Id}] File: {fileLinePositionSpan.Path}, Line: {fileLinePositionSpan.StartLinePosition.Line}, Character: {fileLinePositionSpan.StartLinePosition.Character}: `{e.GetMessage()}`"); }).Aggregate((s1, s2) => s1 + "\n" + s2); throw new ViewRenderException("Failed to compile view `" + view.FilePath + "`: " + message, source, razorCSharpDocument.GeneratedCode); } var assembly = Assembly.Load(assemblyStream.ToArray(), symbolStream.ToArray()); var type = assembly.GetType(view.Namespace + "." + view.ClassName); if (type == null) { throw new ViewRenderException($"Could not find type `{view.Namespace + "." + view.ClassName}` in assembly `{assembly.FullName}`"); } return(type); } }
Type CompileView(string viewPath, IEnumerable <string> fullJsPaths, IEnumerable <string> fullLessPaths, IEnumerable <string> fullViewPaths, string fullViewPath) { var builder = new StringBuilder(); this.AppendHtml(fullViewPaths, builder); this.AppendJavascript(fullJsPaths, builder); // assumes viewPath is of the form "~/areas/{areaName}/path.cshtml var areaName = viewPath.Substring(8, viewPath.IndexOf("/", 8) - 8); this.AppendCss(fullLessPaths, areaName, builder); var viewCompilationData = new RazorViewCompilationData { Name = RazorViewCompiler.GetTypeName(viewPath.Substring(2)), ViewContents = builder.ToString() }; var compiled = this.compiler.CompileFile(viewCompilationData, new Assembly[0], true, fullViewPath); return(compiled); }
// static Assembly GetWebApplicationAssembly(HttpContext context) // { // object app = context.ApplicationInstance; // if (app == null) return null; // // var type = app.GetType(); // // TODO: suspect "ASP" is no longer real/correct // while (type != null && type != typeof(object) && type.Namespace == "ASP") // type = type.BaseType; // // return type.Assembly; // } public Type CompileFile(RazorViewCompilationData view) { var razorCSharpDocument = this.GenerateCSharp(view); return(this.CompileCSharp(view, view.ViewContents, razorCSharpDocument)); }
public Type CompileFile(RazorViewCompilationData view, IEnumerable <Assembly> assembliesToReference, bool includeDebugInformation = false, string debugFilePath = null) { var host = new RazorEngineHost(new CSharpRazorCodeLanguage()); foreach (var @namespace in this.razorConfiguration.GetDefaultNamespaces().Union(this.defaultNamespaces)) { host.NamespaceImports.Add(@namespace); } var engine = new RazorTemplateEngine(host); // host.EnableInstrumentation = includeDebugInformation; // host.InstrumentedSourceFilePath = debugFilePath; GeneratorResults razorResult; using (var textReader = new StringReader(view.ViewContents)) razorResult = engine.GenerateCode(textReader, view.Name, "", debugFilePath); var assemblies = new List <string>(); var appAssembly = GetApplicationAssembly(); assemblies.AddRange(this.defaultAssemblies); assemblies.Add(GetAssemblyPath(appAssembly)); // current app assemblies.AddRange(appAssembly.GetReferencedAssemblies().Select(GetAssemblyPath)); // assemblies referenced by current app assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(GetAssemblyPath)); // loaded assemblies (superset of above line?) // assemblies.AddRange(AssemblyRepository.GetApplicationAssemblies().Select(GetAssemblyPath)); // assemblies in app's folder // assemblies named by configuration var assemblyNames = this.razorConfiguration.GetAssemblyNames(); // TODO: cant just load here, use assembly repos to check uniqueness assemblies.AddRange(assemblyNames.Select(Assembly.Load).Select(GetAssemblyPath)); assemblies.AddRange(assembliesToReference.Select(GetAssemblyPath)); assemblies = assemblies.Distinct(p => Path.GetFileName(p).ToLowerInvariant()).ToList(); var compilerParameters = new CompilerParameters(assemblies.ToArray()); compilerParameters.IncludeDebugInformation = true; compilerParameters.TempFiles.KeepFiles = false; var codeProvider = new CSharpCodeProvider(); var compilationResults = codeProvider.CompileAssemblyFromDom(compilerParameters, razorResult.GeneratedCode); if (compilationResults.Errors.HasErrors) { var errors = compilationResults.Errors.OfType <CompilerError>().Where(ce => !ce.IsWarning).Select(error => String.Format( "[{0}] Line: {1} Column: {2} - {3}", error.ErrorNumber, error.Line, error.Column, error.ErrorText)).Aggregate((s1, s2) => s1 + "\n" + s2); //TODO: Format Errors nicely throw new ViewRenderException("Failed to compile view `" + view.Name + "`: " + errors); } var type = compilationResults.CompiledAssembly.GetType(view.Name); if (type == null) { throw new ViewRenderException($"Could not find type `{view.Name}` in assembly `{compilationResults.CompiledAssembly.FullName}`"); } // // if (Activator.CreateInstance(type) as RazorViewPage == null) // throw new ViewRenderException(string.Format("Could not construct `{0}` or it does not inherit from RazorViewPage", type)); return(type); }